关于DM8168中移植算法速度慢、效率低的新发现

有不少的朋友,特别是刚刚接触DSP的朋友,基于DVRRDK编写C代码发现运行速度特别慢,我在上面简单的对每个像素的UV分量赋值=0x80,这样就成了灰度图像,对1080P图像进行操作,发现处理每帧要耗时10-20ms,真是慢的不可思议。

       最近将SWOSD的完整代码看了一遍发现了玄机。

       主要问题是在DDR中读写数据拖慢了速度。

       经测试SWOSD进行一帧D1的叠加仅需要400us(叠加大小大概208*32*3个窗口);

       仔细分析,其内部使用了基于内部 IALG_DARAM0(双通片上数据存储)的乒乓缓存结构:

[cpp]  view plain copy
  1. Int SWOSD_TI_alloc(const IALG_Params *algParams, IALG_Fxns **pf, IALG_MemRec memTab[])  
  2. {  
  3.     const SWOSD_Params *params = (SWOSD_Params *)algParams;  
  4.   
  5.     memTab[0].size = sizeof(SWOSD_TI_Obj);  
  6.     memTab[0].alignment = 0;  
  7.     memTab[0].space = IALG_DARAM0;  
  8.     memTab[0].attrs = IALG_PERSIST;  
  9.         //InA  InB Out[2]  
  10.     memTab[1].size = (params->maxWidth*(2+2+2+2))*2;  
  11.     memTab[1].alignment = 128;  
  12.     memTab[1].space = IALG_DARAM0;  
  13.     memTab[1].attrs = IALG_PERSIST;  
  14.   
  15.     return (2);  
  16. }  

此函数为TMS320 Algorithm Standard 即xDAIS中的 algAlloc()函数的实现,其返回一个该算法所需的内存记录表。(详见SPRU360E)

[cpp]  view plain copy
  1. Int SWOSD_TI_initObj(IALG_Handle handle, const IALG_MemRec memTab[],  
  2.     IALG_Handle p, const IALG_Params *algParams)  
  3. {  
  4.     const SWOSD_Params *params = (SWOSD_Params *)algParams;  
  5.     SWOSD_TI_Obj *obj = (SWOSD_TI_Obj *)handle;  
  6.   
  7.     if (params == NULL) {  
  8.         params = &SWOSD_TI_PARAMS;  
  9.     }  
  10.   
  11.     obj->swOsdCtrl.openPrm.maxWidth  = params->maxWidth;  
  12.     obj->swOsdCtrl.openPrm.maxHeight = params->maxHeight;  
  13.   
  14.     obj->memLineBuf = memTab[1].base;  
  15.   
  16.     return (SWOSD_SOK);  
  17. }  

在使用时:

 

[cpp]  view plain copy
  1. pLineBufA[0]  = (Int64*)(swOsdObj->memLineBuf + offset);  
  2.   offset += width;  
  3.   
  4.   pLineBufA[1]  = (Int64*)(swOsdObj->memLineBuf + offset);  
  5.   offset += width;  
  6.   
  7.   pLineBufB[0]   = (Int64*)((Int32)swOsdObj->memLineBuf  + offset);  
  8.   offset += width;  
  9.   
  10.   pLineBufB[1]   = (Int64*)((Int32)swOsdObj->memLineBuf  + offset);  
  11.   offset += width;  
  12.   
  13.   pLineBufOut[0] = (Int64*)((Int32)swOsdObj->memLineBuf + offset);  
  14.   offset += width;  
  15.   
  16.   pLineBufOut[1] = (Int64*)((Int32)swOsdObj->memLineBuf + offset);  
  17.   offset += width;  

然后内部将要处理的数据用DMA拷贝到memLineBuf,并使用乒乓结构:

[cpp]  view plain copy
  1. SWOSD_TI_DMA_Fast2D1D  
  2. (  
  3.     dmaHandle,  
  4.     SWOSD_DMA_CH_IN_A,  
  5.     (void *)pInA,  
  6.     (void *)((UInt32)pLineBufA[0] + 0x30000000),  
  7.     width,  
  8.     2,  
  9.     srcPitch,  
  10.     width,  
  11.     srcPitch,  
  12.     (-width)  
  13. );  

至于上面的代码片段中目的地址 (void *)((UInt32)pLineBufA[0] + 0x30000000)中为什么在pLineBufA[0] 加了0x30000000还是没有弄明白,请高人指点

(因为dma是个外设,他看到的地址和dsp看到的地址是不一样的。之间有个0x30000000的偏移。L2 SRAM address is 0x108_00000. The L3 address of c674 L2 SRAM address (GEM UMAP0) is 0x408_0000 .The conversion is from 0x108_0000 to 0x408_0000 by adding 0x0300_0000. DONT USE 0x300_0000 .IT WILL CRASH THE SYSTEM.)

本文目前只总结出了原因,至于实现正在尝试。

欢迎交流沟通。

转载注明:http://blog.csdn.net/guo8113/article/details/25026777

你可能感兴趣的:(关于DM8168中移植算法速度慢、效率低的新发现)