deepin-ocr/3rdparty/ncnn/docs/developer-guide/ncnn-tips-and-tricks.zh.md

47 lines
3.2 KiB
Markdown
Raw Normal View History

### blob内存是隐含共享的
ncnn的blob最初直接使用opencv的cv::Mat后发现blob最多只支持三维因此实现了类似的Mat
Mat的data每个通道内存16字节对齐并且有原子的引用计数a=b不复制数据超级快
Mat支持直接引用外部的内存块不复制数据加快模型加载和输入输出
举个例子split layer 将一个blob复制成n个ncnn中实现为单纯的增加引用计数没有任何数据复制
### 只运算一部分并保留中间结果
ncnn的net在解决分支依赖时是自上而下深度优先的因此当网络有多个分支时运算只会在需要结果的那个分支中进行节约时间
当多个分支有重合部分时,运算其中一个分支后会自动保留其余分支所需的中间结果,隐含共享,以便运算其余分支时利用
举个例子:某网络结构为 A -> B -> C1 + C2向ncnn索要C1结果时运算过程是 A -> B -> C1同时B结果引用计数加1自动保留后面还需要C2结果时只运算C2就足够了
### 开启轻模式省内存
每个layer都会产生blob除了最后的结果和多分支中间结果大部分blob都不值得保留开启轻模式可以在运算后自动回收省下内存
举个例子:某网络结构为 A -> B -> C在轻模式下向ncnn索要C结果时A结果会在运算B时自动回收而B结果会在运算C时自动回收最后只保留C结果后面再需要C结果会直接获得满足绝大部分深度网络的使用方式
### 网络和运算是分开的
ncnn的net是网络模型实际使用的是extractor也就是同个net可以有很多个运算实例而且运算实例互不影响中间结果保留在extractor内部在多线程使用时共用网络的结构和参数数据初始化网络模型和参数只需要一遍
举个例子全局静态的net实例初始化一次后就能不停地生成extractor使用
### openmp虽快但未必合适
ncnn中几乎所有运算都能用上openmp多线程加速而且性能很赞
不过系统有时候会突然慢一下比如手机太热自动降频界面操作等等ncnn耗时也会偶尔抖动变长在计算耗时稳定性比较重要的时候建议关闭openmp或者设置下extractor线程数
举个例子手机自拍时用ncnn进行人脸实时定位如果耗时突然涨一下就会感觉到掉帧而稳定的帧率体验更好
### NCNN_STDIO/NCNN_STRING禁用模型文件
ncnn支持加载自有的模型文件和模型内存NCNN_STDIO控制是否需要支持加载模型文件设成0能禁用这部分代码从而减小库的体积NCNN_STRING设成0能清除大部分可见的字符串和解析过程
模型内存加载时的参数数据是直接引用的,速度更快,通常在手机上使用这种方式
### 削减 ncnn 内置的层实现
cmake的时候加参数 -DWITH_LAYER_xxx=OFF 就可以完全不编译对应的内置层,这样可以进一步减小库的体积
### 关于 ARM big.LITTLE 调度
调用set_cpu_powersave可以把ncnn运算线程控制在特定的cpu核心上大核心速度快耗电多小核心速度慢点但省电大小一起用手机热得快