海思MPP业务MMZ内存优化介绍
概述
完全是本着内存吃紧的情况下的一些优化点,都是在文档有介绍的,自己多调试下就出来了,好不好用,还请自己评估,这里只是给出一些点的介绍。本着有坑也不填的原则,这里只做交流使用,后果自负。
OS内存和MMZ
海思的安防平台芯片的内存主要划分两部分来管理,一部分是系统使用的OS内存,一部分是称为MMZ的内存,具体这两部分如何配置和使用的,文档中已有相当清析的描述了,这里主要介绍一下海思MPP业务里MMZ如何节省内存的一般基本方法。
当然,如果你的内存足够富足,基本按海思给的sample的配置方式就好了,但一些内存比较紧的时候,还是可以做一些工作来优化节省出一定的内存的。
调试的工具
在介绍前,先了解下海思MPP的一些调试工具,主要还是依赖 /proc里的一些信息来优化。
Mpp日记 /dev/logmpp
这个文件里的日记信息,相当重要,在开发海思平台的MPP业务时,是否有错误,有不合理的地方,都有可能这里发现,如果你不会使用这个信息,说明你还真没太了解MPP业务里的东西。
这个文件会打印当前SDK MPP的一些当前运行信息,这个是有个级别可以调试的,如果你想看更详细的信息就把打印的级别调低点,默认会打印警告和错误信,我们在调试内存时就有可能你把内存调得过低了,MPP报错时,最直接的表现即在这里。
MMZ内存分配 /proc/media-mem
这里记录了当前MMZ内存被分配至哪些模块,被谁使用了。
/proc/umap/*
各个模块的调试信息,当然也包括内存的一些使用情况。
以上这些信息,在他的SDK的文档中都有提及介绍了,详细的还是需要细细读一下他的文档。
现在新出的SDK里海思也给出了一个XLS的文档来配置MMZ的一些使用情况,可以参考他的各个模块的内存使用进行优化。
VB内存分配
在海思的MPP里,有一个VB管理内存池的概念,也就是先根据自己各个模块需要的内存,预先分配好一定的内存,各个模块用时从这个池中去取,像他文档里的这个图说的:
可以为各个模块分配不同的VB内存块。
以为VI分配内存为例,一般一个VI通道占用2个VB块,如果你的一个VI的图像通道大小是1080P,那有几个VI通道的图像进来,就对应的分配相应的VB块。
如果使用的VB块大小不同,那就尽量分配不同大小的VB块,MPP会从分配的数组里,从小到大的找到一个合适的内存块使用。
如何确认你分配的内存块数量是否足够?
在/proc/umap/vb中
如以下信息:
IsComm为1时表示是你自己分配的VB内存池,blkcnt是分配的数量,Free是表示当前空闲的个数,MinFree表示历史中最小的空闲个数,如果Free大于0,表示当前使用的是够的,如果MinFree大于0,表示一直有内存块是空闲的。
如何分最少的内存块,不浪费,又不影响业务呢?
还是看MinFree值,调小VB的内存块分配,当MinFree为0时,并且/dev/logmpp里一直没有报使用这个大小VB池的模块的错误,那么就是合适的,内存块也就没有浪费了。
如何合理分配内存块大小
内存块分配合理了,就看内存块的大小分配是否是合理的,如上面的BlkSz为663552,这个值,一般大家都会使用SDK里的sample那个宏公式来计算,但都是计算的有富足,多余的, 一般见到的都是视频业务处理中图像的宽,高,进行一个对齐操作,再乘以2。如果你的内存很紧张,那么就试着不是乘以2,比如乘 3/4,或1/2,如果分配的内存块小了,而又无法从其它的池中获取内存,/dev/logmpp一般会报这个模块需要的内存大小,那么,你可以直把分配他报的这个内存大小去配置这个VB块,MPP会有个内存对齐,有可能实际分配的还是会比你指定的大小大一点。
VB分配就是一个是块的数量,块的大小,不同模块需要不同大小的块时,分别为其分配不同的VB大小的块池,这样一般就不会有什么内存在这上面浪费了。
下面还是以业务的方式来介绍一下MMZ内存使用的一些可以优化的方法。
各个模块使用内存块的大小及数量
每个模块使用的内存块的数量,及大小在不同的芯片上有一些小的差异,建议还是参考海思给出的MPP中模块内存计算的那个XLS文档。
在查看VB块时,如果一些模块占着VB块一直不放,你分配再多的内存都没用,那就要考虑一下是不是性能不够了,在性能不够的情况下,一些模块会一直占着内存块不能释放。
DVR产品
MPP里基本的视频流 VI->VPSS->VENC/VO, VDEC->VO
多年没有搞DVR产品了,主要MPP的两个业务一个是录相,预览,视频的回放。
VPSS
VPSS通道一般可以预先创建放在那里,也不会占用太多的内存,一般我是把业务需要的VPSS建立好不释放。
DieMode模式的使用,数字视频一般就关了,不使用
有一个backup属可以关注一下,这个可以节省不少内存,但副作用也是相当明显的啦!
还有各个通道的功能使用,不过之前内存收益也不太明显,看最近新出的SDK里有一些新添加进来的功能,没有去试过了。
VENC
VENC是个内存大户啊,先确认你使用VENC的内存分配方式,后端的芯片一般都是三种,也就是文档中说的:编码帧存方式
这里以Hi3521A为例,支持两种方式,一种是privateVB,一种是UserVB,具体的内存计算方式见文档,这里如查为了节省内存,就用UserVB方式了。
编码重构帧复用参考帧亮度内存模式,也是一个直接内存节省收益的配置。
码流Buff的配置:这个有两种方式,一般模式和省内存方式,副作用也比较高啊,自己评估,如果内存紧张,也是一个有效的内存节省收益的配置。
VECN的通道创建起来就是需要占用比较大的内存的,一般通道动态的创建,不过DVR中一般都是实时在录相,所以这个一般情况下都是一直创建的。
VO
输出这一个,一个FB的配置上根据自己最大的分辨率指定合适的内存大小,把不用的FB输出的内存配置去掉(load脚本里).
再一个就是VO输出的一些缓存配置,如HI_MPI_VO_SetDispBufLen使用等。
VDEC
VDEC也很占内存,在DVR里一般按需创建VDEC,不用进就把他销毁掉吧,放在那也是很占内存的。
同VENC一样有一个编码帧存方式和码流Buff的配置,如果是回放自身的录相还好吧,VENC相应的配置对应的节省内存配置也无太多的问题。
另一个注意就是在创建通道时,回放多大的录相视频,就创建对应大小的VDEC通道,别创建一个能回放所有视频大小的通道,如果这样做也是很费内存的。
另一个是回放方式的选择上,在回放时,如果性能不够的情况下,内存有可能也被一直占着不释放,你可以使用预览模式试试,这个副作用就是会丢帧啊!
NVR产品
NVR的产品基本同DVR的方式的优化方法类似。最多的也是VDEC,VENC上下做功夫,不重复讲了。
IPC产品
IPC产品这里以3518EV200为例来说一些,因为这家伙只有64MB的内存,看过一些人做的产品内存上还是非常吃紧的。
这里以1080P@20fps + VGA@25fps为例说明,MMZ内存使用上大概在22MB这样子。
1:VI->VPSS使用在线模式,这样能节不少内存,只是ISP里的一些功能用不了了,不过3518E的图像还是在VPSS上做一些优化吧。
2:VPSS开启lowdelay,把VPSS,VPSS两个通道,一个是1080P的主码流,一个是VGA的子码流,把主码流的通道同VENC的编码主通道绑定在一起。
2:VENC,开启H264eMiniBufMode,JpegeMiniBufMod,H264eRcnEqualRef开启,根据这些配置,计算编码的内存大小。
基本也就是上面这些点吧,最重要的两个方面的优化,一个是VB池的使用上,DVR的VENC,NVR的VDEC,IPC的VENC这些文档如都有提及的。同时注内占用MMZ大块内存的地方,看是否有合适的方式修改。
最主要的还是查看/proc/umap里的运行信息,查看各个模块的VB、内存使用情况,是否有报错等。
同样调试完内存,还是得查看/proc/umap里的信息是否正常,如VI里的VB块申请情况,是否有失败的问题,h264e里是否有丢失图像,掉帧。
</div>