ngswfx

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx  发布于  2018-02-03 03:19:30
采纳率 0%
55个问答
6145

海思MMZ剩余内存,利用起来,怎么会cpu占用高呢

 
本帖最后由 ngswfx 于 2018-2-3 03:40 编辑

做解码,实际现场使用,情况多变,有1分割需求,有16分割需求,还有更大的,现有MMZ的分配体系,会导致某些时候MMZ大量剩余,但是操作系统内存不够,很难做到自适应。例如极端的几种情况就是,最大1画面分割,解码1路1080P。这个时候,海思底层MMZ部分内存极大浪费,当分割数逐渐增大,例如对于3536片子,如果是4分割,要支持4个4K,或者到了16路1080P,还想支持16路500万非实时,MMZ内存将会超级紧张,因为为了满足VPSS以及解码显示视频帧需要,MMZ使用了大量内存。当3536到了64分割,情况又来了个大反转,由于全部都是D1图像,MMZ出现极大剩余,但此时操作系统的情况和前面1分割和16分割就完全不一样了,因为操作系统APP层面,为了得到或者解析出逐帧的264 265数据,通常需要缓冲的协助,这个时候即便分配64路500K缓冲,都32M内存占用了,为此1-4-16-64各个分割情况下,内存使用紧张在MMZ层面以及操作系统APP层面之间来回转换,要么时操作系统紧张,要么是MMZ紧张。


前几天我想把海思的MMZ内存充分利用起来,因为MMZ一旦分配,内存就固定了,当系统内存不足时(例如64M系统使用),有的情况下MMZ还很多,我就通过海思的MMZ分配给程序直接使用,来代替比较大的内存需求,例如视频流缓冲块,整个流程下来,也都正常,而且数据也都不大,也就是16个300K-500K左右的缓冲,算下来也就10M左右,只不过是在操作系统环境下使用的,对于整个内存体系而言,10M不算什么,但对于系统环境而言,总共才64M或者96M或者128M,突然多了10M其实很可观了,使用频率大概每秒16×25×2次,16路视频数据写入读取,都已经定版了,开卖了,结果突然发现CPU居高不下,分析了好多原因,最后发现是这么使用不行,只要使用操作系统正常new出来的就没事,mmz搞出来的就不行。


我当时想法就是通过探测操作系统剩余内存,以及MMZ剩余内存,大概10-30秒探测一次,并根据当前系统分割数量,综合考虑,动态使用操作系统部分的内存还是临时借用MMZ内存。


/////////////////////以下是部分实现代码,实际流程已经完毕,解码以及各个部分基本正常,就是cpu高,最后发现就是这里出现问题,只要不是用这种机制,3520D cpu 整体占用通常在10%以内,一旦使用,很可能超过40%。系统很卡。最后没有办法,把3536这些也都临时暂停不是用这种机制了。

通过定义如下接口,代替应用程序APP里面比较大的buffer=new char[300*1024];

int     IVHI_MmzAlloc(HI_U32 *pu32PhyAddr, void **ppVitAddr, const HI_CHAR *pstrMmb, const HI_CHAR *pstrZone, HI_U32 u32Len)
{
        if(HI_SUCCESS==HI_MPI_SYS_MmzAlloc(pu32PhyAddr, ppVitAddr, pstrMmb,pstrZone,u32Len))
                return true;
        else return false;
}
int                 IVHI_MmzFree(HI_U32 u32PhyAddr, HI_VOID *pVirtAddr)
{
        if(HI_SUCCESS==HI_MPI_SYS_MmzFree(u32PhyAddr, pVirtAddr))
                return true;
        else
                return false;
}


简单删除内存实现替换:
#ifdef SUPPORT_USE_MMZ_MEM_RTSP
                if(_MmzFreeCallBack_RTSPEx&&bUseMMZ_265Nal){
                        _MmzFreeCallBack_RTSPEx((unsigned int )pu32PhyAddr_265Nal,(void *)(m_pNaluBuf));
                        m_pNaluBuf=NULL;
                        pu32PhyAddr_265Nal=0;
                        bUseMMZ_265Nal=false;
                }else{
                        delete []  m_pNaluBuf;
                        m_pNaluBuf=NULL;
                        bUseMMZ_265Nal=false;
                }
#else
                delete [] m_pNaluBuf;
#endif

创建内存实现替换: 注意底下的_MmzAllocCallBack_RTSPEx其实就是HI_MPI_SYS_MmzAlloc,只不过函数接口通过回调赋值而已
        if(0 == m_uNaluBufSize)
                        m_uNaluBufSize = 256*1024;
                else
                        m_uNaluBufSize *= 2;
                char * pTemp = m_pNaluBuf;
                unsigned int old_pu32PhyAddr_265Nal=pu32PhyAddr_265Nal;
                bool old_bUseMMZ_265Nal=bUseMMZ_265Nal;
#ifdef SUPPORT_USE_MMZ_MEM_RTSP
                                                bUseMMZ_265Nal=false;
                                                if(_MmzAllocCallBack_RTSPEx&&bCanUseMMZ_Memory_RTSP){
                                                         char pstrMmb[32];
                                                         memset(pstrMmb,0,sizeof pstrMmb);
                                                         sprintf(pstrMmb,"RTSP_265Nal");
                                                        if( _MmzAllocCallBack_RTSPEx((unsigned int *)&(pu32PhyAddr_265Nal),(void **)&(m_pNaluBuf),(const char *)pstrMmb,NULL,m_uNaluBufSize))
                                                                bUseMMZ_265Nal=true;
                                                }
                                                //如果MMZ没有分配成功
                                                if(!bUseMMZ_265Nal&&!m_pNaluBuf){
                                                        m_pNaluBuf=new char[m_uNaluBufSize];
                                                }
#else
                m_pNaluBuf = new char[m_uNaluBufSize];
#endif

////////一旦分配完毕,使用内存的时候,都是针对m_pNaluBuf进行memcpy这类常规操作包括考入或者考出。突然想起来,有一个地方好像忽略了使用频次,在进行单帧解析时,好像是对这个内存进行了逐字节处理的。但想不通这个和普通new出来的内存有啥区别。



//////////////大家谁这么用过,有过经验或者想法的,可以讨论一下。当然3798M没这个问题,因为都是抢总内存用。




我来回答
回答4个
时间排序
认可量排序

AOC

0个粉丝

19

问答

0

专栏

15

资料

AOC 2018-02-03 14:22:31
认可0
还没想过linux分配给内核的空间可以动态调整

mengxp

0个粉丝

18

问答

0

专栏

1

资料

mengxp 2018-02-03 14:52:11
认可0
我估计这样出来的内存没有经过cpu缓存处理。

hero

0个粉丝

1

问答

0

专栏

0

资料

hero 2018-02-05 08:45:58
认可0
每次改变分割模式重新启动,调整MMZ分配行不?运行状态调整MMZ,OS 启动完全,应该无法调整MMZ了:lol:lol:lol:lol:lol

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2018-02-05 09:05:54
认可0
本帖最后由 zhuangweiye 于 2018-2-5 09:08 编辑

试试带cache的函数 HI_MPI_SYS_MmzAlloc_Cached,  新的3536C有HI_MPI_SYS_MmapCache, 可惜3536没有
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区