前言¶
本文为进行小型化开发的程序员而写,目的是介绍在单板上进行Linux开发、裁剪、优化及使用注意事项等内容。
说明: 未有特殊说明,SS927V100与SS928V100内容完全一致。
与本文档相对应的产品版本如下。
本文档(本指南)主要适用于以下工程师:
技术支持工程师
软件开发工程师
综述¶
DDR小型化可以从多个方向入手:uboot、kernel、filesys、SDK、APP都可以在内存使用上做一定程度的优化。本文主要是对SDK和APP的小型化进行简单的说明。
基于 SS626V100的SDK目前支持运行Linux和liteos双系统或单linux系统,如业务场景只需运行单linux系统,可参考《内存布局调整指南》3.2章节裁剪liteos系统相关MMZ占用。本文中默认以Linux和liteos双系统为基础进行描述。SS626V100的系统小型化基于DEMO单板实现,以容量为2G Bytes的DDR内存为例。
其中基于SS626V100典型场景业务的MMZ内存占用数据,请参考《SS626V100 Memory Usage Statistics Report》。此外,客户业务的具体内存占用,需结合具体场景进行分析,下文介绍各模块MMZ内存占用及小型化可优化手段。
主要模块工作占用MMZ情况¶
一般业务中MMZ的占用往往是内存消耗的很大一部分,本章节主要介绍一般业务场景中几个主要模块工作时占用MMZ的情况。
VI¶
VI采集状态下最多会占用三个视频帧VB。一个用于当前帧采集,一个用于准备给下一帧采集,一个在轮转流程中(主要是后级模块占用)。
SS928V100中 MMZ占用:
vi(%d)_model_%d:每路pipe需占用两个一定大小模板MMZ内存,大小与通路宽度相关,宽度小于等于4096时大小为16KB。
vi(%d)_lmf:每路pipe开启LMF功能时占用MMZ内存,用于存放LMF的系数,固定值4K。
vi(%d)_bnr_mot:每路pipe开启Bayer NR功能时需要占用的motion buffer内存,大小由处理图像大小的宽高决定。
vi(0)_bnr_rnt:每路pipe开启Bayer NR功能时需要占用的rnt内存,大小由处理图像大小的宽高决定;离线时个数由ss_mpi_vi_set_pipe_bnr_buf_num。
接口设置,默认为40块。
vi(0)_bnr_ref%d:每路pipe开启Bayer NR功能时需要占用的时域参考内存,大小由处理图像大小的宽高决定。
VDEC¶
VDEC MMZ占用分为buffer占用、轮转占用和设备占用。
vdec(%d)_stream:解码码流Buffer相关内存,为用户指定大小和驱动内部分配之和。SS626V100包括PTS数据存放内存。
vfmw(%d)_usd_buf:用户数据Buffer内存,大小根据用户指定的进行分配。
vdec(%d)_adp_ref:用于存储通道使用vb的相关信息。
vdec(%d)_adp_event:用于存储解码过程中产生的event信息。
vfmw(%d)_shr_img:用于存储解码出图像的相关信息。
vdec_adp_proc:用于存储mdc侧vdec产生的proc信息。
vfmw_mdc_shr:用于存储mdc侧vfmw产生的proc信息。
vfmw(%d)_seg_buf:SCD切码流后存放内存,与分辨率相关,与协议无关。
vfmw_scd_msg:SCD逻辑工作时需要的内存,固定值为44Kbytes。
vfmw(%d)_vdh_msg:VDH逻辑工作时需要的内存,与模块参数中设置最大slice个数相关,默认模块参数(slice 600个)时大小为616KBytes。SS626V100此块内存名称为vfmw_vdh_msg。
vfmw_vdh_ext:VDH逻辑工作时需要的内存,与模块参数中设置的最大宽高相关。SS626V100默认模块参数(宽高8192x8192)时大小572KBytes。
vfmw_mdma_msg:VDH逻辑工作时需要的内存,固定值44KBytes。
vdec(%d)_pic_vb:vb大小和个数都由用户配置。私有vb模式下,大小根据用户配置通道属性中frame_buf_size确定,个数根据用户配置通道属性中frame_buf_cnt确定。
vdec(%d)_tmv_vb:vb大小和个数都由用户配置。私有vb模式下,大小根据用户配置通道属性中tmv_buf_size确定,个数为 “参考帧+1”,其中参考帧个数根据用户配置通道属性中ref_frame_num确定。
VPSS¶
vb_pool: Group占用两块VB (前级模块送来:当前工作VB+Backup 帧),每个使能通道会获取通道大小的VB(通道模式为Auto时,为后端模块获取),硬件处理完成后会发送到后端绑定模块。如果需要做旋转/二级缩放功能,还需申请中间的临时VB(公共VB)。
vpss(%d)_src:每组需占用亮度和MMZ内存资源,约4K大小。
vpss(%d)_dci:每组开启DCI功能时占用MMZ内存,约4K大小。
vpss(%d)_model:每组需占用一定大小模板MMZ内存。大小与模块参数中的split_node_num以及组的max_width有关。split_node_num和max_width越大,占用大小越大。
vpss(%d)_lmf:每组开启LMF功能时占用MMZ内存,用于存放LMF的系数,固定值4K。
vpss(%d)_rgn_luma:每组开启通道亮度和功能时占用MMZ内存,用于存放亮度和统计信息,固定值4K。
vmallocinfo:每组上下文需占用一定大小OS内存。总大小与组数量相关,组越多占用越大。
VGS¶
VGS模块根据job、node、task数目,分配固定的MMZ内存。
vmallocinfo:根据job、task数目及上下文占用OS内存。数目越多占用越大。
vgs_node_buf:根据node数目,占用一定大小的MMZ内存。数目越多占用越大。
VENC¶
硬件相关:
vedu_hal_(%d):硬件需要使用的内存,与IP个数相关。
通道相关内存(以H264为例,H265则前缀为h265e):
h264e(%d)_node:寄存器节点配置内存,每个通道一块。
h264e(%d)_str0:码流buffer,每个通道一块。
h264e(%d)_rcn(%d):参考帧重构帧内存,个数与编码参考帧个数相关。
h264e(%d)_info(%d):参考帧重构帧信息内存,个数与编码参考帧个数相关。
h264e(%d)_deblur:通过ss_mpi_venc_set_deblur 使能去模糊后,需要相应去模糊处理内存。
h264e(%d)_md:通过ss_mpi_venc_set_md使能MD检测,需要相应的MD检测内存。
venc(%d)_svc:通过ss_mpi_venc_enable_svc使能SVC,需要相应的SVC内存。
jpege(%d)_stm:jpege码流buffer,每个通道一块。
jpege(%d)_roi_map:通过ss_mpi_venc_set_jpeg_roi_attr使能roi_map,为jpege的roi_map分配内存。
vmallocinfo:各个通道的通道上下文内存;UserData数据;码率控制相关内存。
VO¶
VO MMZ占用分为系数MMZ占用、获取亮度和MMZ占用,VB轮转MMZ占用。
系数MMZ占用:
vo_coef_buf:回写缩放系数(128KB)和多区域配置系数(8KB)的内存存放占用, 共计136KB。如果芯片不支持回写缩放,则不会申请对应系数,一个多区域占用4KB内存,两个多区域占用8KB.
获取亮度和MMZ占用:
vo(%d,%d)_luma:VO模块获取视频层和通道亮度和时动态申请MMZ内存占用,某个通道固定占用4KB。如果芯片不支持获取亮度和,则不申请此内存。
VB轮转MMZ占用:
vo(%d)_disp_buf:vb大小和个数都由用户配置。大小根据用户配置视频层属性img_size确定,个数根据用户配置视频层属性中display_buf_len确定。Single模式下VO会占用3块私有VB用来显示轮转。
Multi模式下,如果前端绑定VPSS为auto模式,VO会占用4块私有VB用来显示轮转;如果前端为User模式,VO可以不分配VB,此时占用前端模块发送过来的VB,显示完后释放。
GFBG¶
加载ko时,用户指定图形层、鼠标层的显示buf大小。支持的图层均可指定,图层id号与vram id号需保证匹配。
例如:insmod gfbg.ko video="gfbg:vram0_size:32400,vram1_size:32400,vram2_size:256,vram3_size:4052".
vram0_size: 对应gfbg0图形层内存大小,单位KB,对应mmz name= gfbg_layer0。
vram1_size: 对应gfbg1图形层内存大小,单位KB,对应mmz name= gfbg_layer1。
vram2_size: 对应gfbg2图形层内存大小,单位KB,对应mmz name= gfbg_layer2。
vram3_size: 对应gfbg3图形层内存大小,单位KB,对应mmz name= gfbg_layer3。
AUDIO¶
ai(%d)_frm:AI的通道buffer根据chn_cnt、frame_num和point_num_per_frame分配。
ai(%d)_dma:AI的DMA缓冲区根据chn_cnt和point_num_per_frame分配。
ao(%d)_dma&frm:AO的DMA缓冲区和通道buffer根据chn_cnt、frame_num和point_num_per_frame分配。
ao(%d, %d)_cir:音频帧buffer根据frame_num和point_num_per_frame分配。
aenc(%d)_strm:码流buffer根据buf_size分配。
aenc(%d)_cir:环形缓冲区根据编码通道数分配。
REGION¶
去掉不必要的模块可以减少内存的占用,如:
模块加载时分配的1024个区域信息上下文节点,占用os内存4kb。区域信息上下文在创建区域时动态分配。
如果是overlay或者是overlayex类型的区域,还会创建乒乓buff用于存放位图数据。
rgn_pin_pon_(%d):乒乓buff的大小由用户设置的width,height,canvas_num和颜色格式决定,占用MMZ内存。
其他模块调用REGION的函数向REGION注册信息时动态分配,占用MMZ内存。
TDE¶
通道使用MMZ,为固定值总大小:(OT_TDE_CMD_NUM) * 64 + (OT_TDE_JOB_NUM) * 96 + (OT_TDE_NODE_NUM) * 256 +(OT_TDE_FILTER_NUM) * 1024。
SVP¶
SVP_NNN内存占用分为MMZ内存和os内存,其中MMZ内存包括任务节点和推理内容内存。
节点MMZ占用:
内核态节点的大小,默认值100KB;
用户态节点的大小,默认值80KB。
推理MMZ占用(Resnet50 Batch 1典型场景):
OM内存大小,值50828KB;
输入输出数据内存大小,值8596KB;
模型信息内存大小,值12KB。
OS内存占用:
OS内存主要包括两部分:静态全局变量的内存,大小大约5.6KB;动态内存,大小大约0.594KB。
说明:
SS927V100不支持SVP_NNN模块。
IVE内存占用分为MMZ内存和os内存,其中MMZ内存包括任务链表和辅助内存。
任务链表MMZ占用:
ive_queue: IVE任务链表的大小,默认为212KB。
辅助MMZ内存占用:
ive_tmp_node: IVE的多算子组合任务需要的临时节点,固定值4KB。
Md_proc: MDproc信息需要的MMZ内存,固定值8KB。
ive_resize_param: resize算子计算需要的辅助内存,固定值9264Byte.
ive_yuv_to_hsv_table: ive颜色空间转换存放table的辅助内存,固定值2048Byte
ive_yuv_to_lab_table: ive颜色空间转化存放table的辅助内存,固定值6656Byte
OS内存占用:
ive占用的OS内存主要分为kmalloc开辟的内存和静态全局变量占用内存,OS内存加mmz内存不超过235KB。
KCF内存占用分为MMZ内存和OS内存,其中MMZ内存包括任务链表和辅助内存。
任务链表MMZ占用:
kcf_queue: KCF任务链表的大小,固定值106688Byte。
辅助MMZ内存占用:
kcf_param: KCF计算需要的辅助内存,固定值45328Byte。
OS内存占用:
KCF占用的OS内存主要分为kmalloc开辟的内存和静态全局变量占用内存,OS内存加mmz内存不超过150KB。
MAU内存主要分为MMZ内存和OS内存,其中MMZ内存为任务链表的内存。
任务链表占用:
svp_mau_queue: MAU任务链表的大小,默认160KB。
OS内存占用:
MAU 占用的os内存主要有mem_info链表内存使用os内存,mem_info链表内存占用(40 * mau_max_mem_info_num)Byte,以及mau上下文的静态全局变量占用的内存。os内存加mmz内存总共不超过163KB。
PCIV¶
PCIV MMZ占用分为pcie-mcc消息池占用、window占用、VB轮转占用。
pcie-mcc消息池占用:
用于pcie-mcc消息通信,在加载从片pcie驱动时指定位置与大小,大小固定为1M。
window占用:
主片发起DMA操作时,从片空间只能在窗口上读写,加载osal驱动时指定mmz名为window,默认大小7M,起始位置紧跟pcie-mcc消息池之后(pcie-mcc消息池+window连续空间最大8M)。
VB轮转占用:
主片轮转VB:VB大小和个数由用户配置,大小必须保证能接收完整图像,一般根据通道属性中的图像宽高,格式属性等确定;分配释放由用户调用接口控制;接收从片图像时,轮转VB往后传,通过查询后端占用情况决定是否接收下一次轮转。
从片轮转VB:从片接收前端图像,如果是VPSS使用auto模式送帧,则由pciv获取VB,其他模式则接受图像时占用VB;直通模式(PCIV透传)则DMA发送完成释放VB;非直通模式(OSD、缩放等操作),需要获取VGS写出VB,并释放接收图像VB,DMA发送完成后,释放VGS写出VB。
GDC¶
GDC模块根据job、node、task数目,分配固定的MMZ内存。
vmallocinfo:根据job、task数目及上下文占用OS内存。数目越多占用越大。
gdc_node_buf:根据node数目,占用一定大小的MMZ内存。数目越多占用越大。
gdc_int_pole_coef:存储插值系数需要的MMZ内存,固定值4KB。
CIPHER¶
固定大小(驱动内部确定申请的MMZ内存的长度)
Hash初始化:给SHA节点链表分配内存,固定值28 *255* 1=7KB;255作为链表最大深度,最小深度为2;HASH消息的DMA内存:逻辑只识别物理内存,需要申请最大的64KB物理内存存储hash消息。
Cipher驱动模块初始化:给CIPHER节点链表分配内存entry list size(20KB),用来存放16个通道每个通道CCM GCM aad的物理内存padding buffer(2KB),固定值22KB。
非固定大小(由用户层接口传入的MMZ内存申请的长度)。
cipher加解密:依赖虚拟地址/物理地址加解密接口的参数byte_len。
DCC¶
dcc_msg_buf:SS626V100使用,用于双核通信任务。
VDA¶
vda(%d):通道内部计算结果存储相关内存,主要包括SAD结果内存、RGN运动区域信息内存和背景。
ISP¶
isp[%d].vreg[%d]:外部虚拟寄存器内存。
isp[%d].proc:用户态算法proc调试信息。
isp[%d].trans:dng, dcf, colorgammut等信息内存。
isp[%d].ldci:ldci算法内存。
isp[%d].clut:clut算法内存。
be_lut_stt[%d]:be lut信息内存。
pre_on_lut_stt[%d]:在线通路ADVANCED模式be lut信息内存。
isp[%d].stat:统计信息(FE,BE)内存。
isp[%d].fe_stat:FE统计信息内存。
isp[%d].wdr:wdr算法内存。
isp[%d].drc:drc算法内存。
isp[%d].be_cfg:离线通路be config buffer。
isp[%d].be_stt_on:在线通路be统计信息内存。
isp[%d].fe_stt:fe统计信息内存。
isp[%d].be_stt:离线通路be统计信息内存。
isp[%d].stit_fe:拼接通路fe统计信息内存。
isp[%d].stit_be:拼接通路be统计信息内存。
HNR¶
hnr_pqp_buf[%d]:hnr模型文件内存。
hnr_ping_pong_buf:hnr模型推理使用的工作内存。
开启HNR功能参考帧模式需要多占用4~6个视频帧VB,无参考帧模式需要多占用1个视频帧VB。
各模块内存相关可优化配置¶
VB¶
公共VB池、模块VB池、UserVB池的个数设置参见《MPP 媒体处理软件 V5.0 开发参考》“系统控制章节”的VB相关接口。 |
|||||
公共VB池、模块VB池、UserVB池的VB块大小设置参见《MPP 媒体处理软件 V5.0 FAQ》“系统控制章节”的VB相关接口。 |
SYS¶
|
|||||
|
VI¶
VDEC¶
说明: 具体参见《MPP媒体处理软件V5.0开发参考》"视频解码”章节。
VPSS¶
|
|||||
|
|||||
split_node_num与输入分辨率的宽成正比,默认为3。当场景固定且为小分辨率时,可调小其值;超大分辨率时,选择合适的取值,避免浪费内存。 |
说明: 具体使用方法及限制参见《MPP媒体处理软件V5.0开发参考》“视频处理子系统”章节。
VGS¶
VGS模块主要是OS内存和node用的mmz。考虑场景的减小最大job数、最大task数和最大node数可以降低些OS占用内存以及node占用的MMZ内存。
说明: 具体使用方法及限制参见《MPP媒体处理软件V5.0开发参考》“视频图形子系统”章节。
VENC¶
说明: 具体参见《MPP媒体处理软件V5.0开发参考》"视频编码”章节。
VO¶
说明: 具体参见《MPP媒体处理软件V5.0开发参考》"视频输出”章节。
GFBG¶
加载ko时,叠加图形层的显存大小根据像素格式、分辨率大小、buf模式算出,用户可以根据实际使用场景来得出需要的显存大小。
非压缩:按实际UI大小,像素格式,单双BUF计算分配:
例:1080P argb8888 双buf模式,
buf_size = 1920 * 4 * 1080 * 2 / 1024 = 16200KB
压缩:argb8888像素格式,宽>=320的情况下,相对于非压缩情况可节省内存45%:
例:1080P argb8888 双buf模式,
buf_size = (1920 * 4 * 1080 * 2 / 1024)* 55% = 8910KB
SS626V100在线画框可节省G3的MMZ内存, 若仅G3用作在线画框时可以不分配G3的MMZ。 G4用作在线画框时也一样。
|
AUDIO¶
ss_mpi_ai_set_pub_attr:chn_cnt、frame_num、point_num_per_frame |
|||||
ss_mpi_ao_set_pub_attr:chn_cnt、frame_num、point_num_per_frame |
说明: 参考文档《MPP 媒体处理软件 V5.0 开发参考》“音频”章节。
REGION¶
用户分配乒乓buff指定的width,height按需要尽可能小。
当区域类型为overlay/overlayex格式时,可以设置pixel_format为CLUT2/CLUT4,CLUT2相比ARGB1555可节省7/8的内存,CLUT4相比1555可节省3/4内存。此方法会降低图像质量。
overlay/overlayex可采用单buff模式,方法为把区域属性中的canvas_num设置为1,当图像需要频繁刷新时可能会出现撕裂效果。
参考文档《MPP 媒体处理软件 V5.0 开发参考》“区域管理”章节,proc信息查看命令cat /proc/umap/rgn。
ss_mpi_rgn_create: pixel_format 设置为OT_PIXEL_FORMAT_ARGB_CLUT2 |
|||||
ss_mpi_rgn_create: pixel_format 设置为OT_PIXEL_FORMAT_ARGB_CLUT4 |
SVP¶
转换模型时配置参数
ATC --batch_num参数配置1,可以减少输入输出及workbuf的内存占用。
ATC --online_model_type参数配置为0,此配置使转换的模型不带调试相关信息,减少模型占用内存。
量化参数配置
activation_quant_params - num_bits配置为8
weight_quant_params - num_bits配置为4
备注:该配置参数会影响模型精度。
KO模块参数
可以通过模块参数svp_nnn_max_task_node_num来更改任务节点个数,从而减少任务节点占用mmz内存。
workbuf共享
同一条流上的多个模型之间可以使用同一块workbuf,从而减少mmz内存占用。
说明:
SS927V100不支持SVP_NNN模块
转换模型时配置参数:ATC -enable_single_stream=true,使能一个模型使用一条流。
多个模型串行推理时,使用aclmdlLoadFromFileWithMem或者aclmdlLoadFromMemWithMem加载方式,手动分配workbuf内存,然后多模型共享同一块工作内存,从而减少mmz内存占用。
MD的proc信息的内存只有在支持MD的时候才会进行分配。
用户不调用IVE的resize,kcf和csc这3个算子不会开辟resize,kcf和csc对应的辅助内存。
可以通过配置模块参数max_node_num来控制链表节点个数,减小链表节点占用的MMZ内存。
可以减少使用核数,从而减小内存。
用户不调用ss_mpi_svp_mau_add_mem_info接口记录mem_info时,不会分配mem_info链表内存,如果用户需要调用ss_mpi_svp_mau_add_mem_info接口记录men_info,可以通过配置模块参数mau_max_mem_info_num来控制存储mem_info内存大小。
可以通过配置模块参数mau_max_node_num来控制链表节点个数,减小链表节点占用的MMZ内存。
VDA¶
加载vda模块ko时设置模块参数最大通道数g_vda_max_chn_num,省OS内存。
PCIV¶
window占用:如果不涉及主片发起的DMA任务,window空间可不用分配,需要注意,如果不分配window空间,需要留意mmz空间完整性,不要被pcie_mcc的空间分割。
VB轮转占用:
主片轮转VB:用于接收绑定图像,如果只用DMA功能,可不分配;如果传输效率够(图像小,帧率低),可使用单buff,个数只分配一个。
从片轮转VB:接收绑定图像时,尽量使用直通模式;仅用户DMA传输时,不占用和分配轮转VB。
GDC¶
GDC模块主要是OS内存和node用的mmz。考虑场景的减小最大job数、最大task数和最大node数可以降低些OS占用内存以及node占用的MMZ内存。
CIPHER¶
|
|||||
可减小链表深度减少链表的内存总大小;可根据实际场景不适用CCM/GCM就删除给CCM/GCM申请的padding buffer |
|||||
|
ISP¶
HNR¶
其它措施¶
限制栈大小¶
默认的栈大小为8192KB,如果内存较小时,会导致线程创建不成功。根据实际的业务需要的栈空间,修改栈的限制大小为1024KB,如果业务更少则可以改成512KB或者更小。
有两种方法可以修改栈大小:
使用 ulimit –s 1024 命令,在应用程序启动之前调用一次;
在main函数最开始调用函数 pthread_attr_setstacksize 也可实现对单个应用程序修改栈空间的目的。
优化代码中内存使用¶
优化代码中内存使用,特别是对栈、堆、常量、全局变量的使用,主要需要注意:
避免应用程序代码中申请后不用的变量;
不要随意申请大块的内存,够用即可;
冗余的内存使用还包含不用的功能模块的初始化。
应用程序中禁用fork、system等进程创建函数¶
由于主进程的数据段占用内存已经很多,如果fork子进程必定消耗大量内存而且会有大概率失败,那么应用程序中应该禁用fork、system等进程创建函数:如bspmm调用、mkfs.vfat调用等。
根据场景去掉不必要的模块¶
去掉不必要的模块可以减少内存的占用,如:
使用gfbg 0buffer或者标准模式,TDE可不加载,如果TDE未加载,则REGION使用memcpy进行Overlay/OverlayEx的拷贝;
无需音频输入、编码场景,AI、VENC可不加载;
无需使用REGION的场景,REGION可不加载;
无需使用JPEGE场景,jpege模块可不加载。
