前言

前段时间因为项目需求,搞了一段时间的前向优化,主要参考了Facebook 18年开源的神经网络加速库QNNPACK。

QNNPACK针对INT8的量化网络,对神经网络的各个算子都提供了非常高效的优化方案,传言其卓越的性能几乎击败了全部已公开的加速算法,不管真假,就优化方案而已个人觉得还是比较新颖,值得好好研究的。到目前为止,QNNPACK已经开源一年多了,除了不多的官方资料之外,民间资料也是最近几个月才陆陆续续出现一些(文章后面会贴出链接),觉得有必要对QNN做一个细致的记录,这里写个QNN专栏方便大家参考交流。

本篇仅作为开篇引言,主要说一些宏观的东西,内容基本都会在官方文档上面找到,短期内会补上对QNN的详细介绍。文章内容会偏重于对QNN源码的分析以及工程的实现,当然在介绍的过程中会结合算法对方案的优势进行说明。详细的宏观算法设计可参考知乎大神的文章神经网络加速库 QNNPACK 实现揭秘;facebook官方文档也可参考,就是比较粗略;前不久QNN的作者也发表文章介绍了qnn加速的核心思想(ps:作者Marat Dukhan从facebook跑路google了,文章署名也是现任公司google...., QNN估计是要停更了)。

QNNPACK初识

为了让这篇文章不会显得毫无价值,接下来会对QNN的优化方案做一个宏观的介绍,让各位心里有个数。QNN的数据流通为UINT8类型,图像内存分布为NHWC模式,内核库包含常见的Conv/Depthwise Conv、Deconv、各种Pooling、Eltwise Sum等网络算子。本文默认读者了解神经网络量化原理,不清楚的也不影响看懂,想了解的话看这篇文章。

每个算子从代码逻辑上可以分为三个阶段:

第一:卷积的数据准备,这一步可以说是精华所在,整个算法实现的基础了。这一阶段涉及输入相关的间接内存缓冲区(Indirext Buffer)的计算以及对权重数据的分块重排;

以卷积为例,QNNPACK 实现了 4×8 的和 8×8 两种计算核(micro kernel),分别用于支持 armv7 和 arm64 指令集的处理器。这两种计算核在原理上区别不大,后者主要利用了更多的寄存器和双发射(Dual Issue)以提高计算的并行度。

图一:间接缓冲区

QNN的一大亮点就是使用了Inter Buffer。常用的Im2col优化算法存在两个问题,第一是占用大量的额外内存,第二是需要对输入进行额外的数据拷贝。这两点如何才能解决呢?间接卷积算法给出的答案是间接缓冲区(Indirect Buffer),如图一右半所示。

Im2col 优化算法首先将输入拷贝到一个矩阵中,如图一中 Input 的相关箭头,然后执行矩阵乘操作。间接卷积优化算法使用的间接缓冲区中存储的其实是指向输入的指针(这也是间接卷积优化算法要求输入内存地址固定的原因)。在代码实现时,第一阶段就需分配好每一层输入的内存空间将Indirect Buffer要指向的区域固定,在第二阶段运行的时候将每一层的输入都放到第一阶段分配的指定内存块中,之后就可以利用Inter Buffer(便于介绍,后文将用二级指针替换Inter Buffer的说法)来对输入数据进行操作了。

第二:运行,在NHWC数据模式的加持下,qnnpack的解决方案使得cache的利用率空前提高,NEON并行原语及NEON汇编也得以大放光彩。

第三:内存清理,就不说了。

文章有关QNNPACK原理的内容部分会参考神经网络加速库 QNNPACK 实现揭秘以及通用矩阵乘(GEMM)优化与卷积计算,感谢两位大佬。文章毕竟是从源码逆向推理,如果存在分析错漏还请各位小伙伴帮忙指正。

QNNPACK高性能前向内核库全面剖析——引言篇相关推荐

  1. Go内核源码剖析 一 程序执行启动过程

    go内核源码剖析 一 这篇是看雨痕大佬的书所做练习的笔记,(其实后面部分基本都是抄的,但是都实践了) 由于电脑抽风,使用的是win10的Linux子系统,功能不完善,很多跟踪支持性不好(可以算是抄的原 ...

  2. 微信 日志服务器 并发大,微信高性能线上日志系统xlog剖析

    微信高性能线上日志系统xlog剖析 做移动开发的同学经常会遇到一个头疼的问题,就是当用户反馈一些问题,又比较冷僻难以复现的时候(不是Crash),常常就会陷入一筹莫展的境地.因此,很多人就研发了相关的 ...

  3. libgo高性能网络服务器,【开源】gnet: 一个轻量级且高性能的 Golang 网络库

    ![](https://ask.qcloudimg.com/http-save/1303222/sipe2g9n9h.png) # Github 主页 [https://github.com/panj ...

  4. 服务器系统goha,推荐一个轻量级且高性能的 Golang 网络库:gnet-Go语言中文社区...

    image Github 主页 博客原文 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于 Event-Loop 事件驱动的高性能和轻量级网络 ...

  5. 【开源推荐】gnet: 一个轻量级且高性能的 Go 网络库

    Github 主页 https://github.com/panjf2000/gnet 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于事件驱 ...

  6. android log耗性能吗,一个高性能的Android日志库

    clue 一个高性能的Android日志库. 为什么性能高 通常的Android日志库, 为了获取到class名, 方法名, 行号, 都是通过以下API实现的: StackTraceElement[] ...

  7. 查询优化器内核剖析第一篇

    查询优化器内核剖析第一篇 查询优化器内核剖析第一篇 查询优化器内核剖析第二篇:产生候选执行计划&执行计划成本估算 查询优化器内核剖析第三篇:查询的执行与计划的缓存 & Hint提示 查 ...

  8. Spark PersistenceEngine持久化引擎与领导选举代理机制内核原理深入剖析-Spark商业环境实战...

    本套系列博客从真实商业环境抽取案例进行总结和分享,并给出Spark源码解读及商业实战指导,请持续关注本套博客.版权声明:本套Spark源码解读及商业实战归作者(秦凯新)所有,禁止转载,欢迎学习. Sp ...

  9. 看门狗超时前在内核打印信息

    前不久,有几台设备一直在无故复位,虽然我很怀疑是应用程序搞死设备的,但公司的人员一向都是自己找不到问题就赖内核.对于这个复位,我的意见是禁止看门狗再测试,但没人理会,因此我想在看门狗超时前在内核里打印 ...

最新文章

  1. mybatis 操作动态表+动态字段+存储过程
  2. 集成开发环境(IDE)
  3. new Date(2019-05-10 08:00:00) 格式在IE内核或者低版本浏览器中显示NaN或者Invalid Date的问题...
  4. 那些年我们薅(撸)过的电子羊毛(设备)
  5. 透过 OKR 进行项目过程管理
  6. html5按钮样式具有子项目,如何使用HTML5+css3制作出12种常用的按钮开关样式(附完整代码)...
  7. Eclipse 的常见报错、警告和原因分析、解决方式以及相关操作快捷键小结(持续更新)
  8. IDEA通过Database连接MySql数据库
  9. 钉钉微应用怎么进入_钉钉微应用如何打开本地app (Android)-问答-阿里云开发者社区-阿里云...
  10. html关机命令,自动关机命令 定时关机命令
  11. 蝴蝶效应、青蛙现象、鳄鱼法则、鲇鱼效应…… 好多新名词 :)
  12. 宁波实训day1: java web开发常用工具安装
  13. qq邮件如何设置html阅读,使用qq邮箱发送html格式的邮件
  14. 公司新加了一台友宝自动售货机引发的思考-适配者模式
  15. 华为云数据库VS自建数据库,上“云”不是智商税
  16. 网页版Photoshop,
  17. restful 验证码平台请求验证
  18. Java好学吗?现在待遇如何?
  19. ESP32-C3入门教程 系统篇①——FreeRTOS系统时钟Tick
  20. 毕节一中2021高考成绩查询,毕节第一中学2021年招生录取分数线

热门文章

  1. angularjs 缓存详解
  2. jquery中$(document).ready(function(){//todo});window.onload时间线关系
  3. storm安装笔记以及提交拓扑任务
  4. 在log4j中使用自定义的Appender
  5. 负数的十进制转二进制
  6. C# 系统应用之使用Pancel控件同一窗体切换页面
  7. App设计灵感之十二组精美的外卖App设计案例
  8. HarmonyOS之公共事件的发布、订阅与退订
  9. npm : 无法加载文件 D:\Program Files\nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本。
  10. python函数每日一讲 - cmp(x,y)