一种基于dm642的二维dct的优化方法

文档序号:7704615阅读:108来源:国知局
专利名称:一种基于dm642的二维dct的优化方法
技术领域
本发明涉及数字图像和视频信号处理,更明确地说,涉及从DM642的指令角度优化DCT函数的方法DCT变换。
背景技术
H264具有很高的数据压缩比率,同等图像质量的条件下,H.264的压缩比是MPEG-2的2倍以上,是MPEG-4的1.5~2倍,但是,高压缩比和出色的画质给视频编码能力带来了很大的挑战。DCT变换是H264编码中最耗时的计算模块之一,在实时编码系统中,对它的计算速度的提升要求是精益求精。TMS320DM642DSP是TI德州仪器公司推出的一款高性能数字多媒体处理器,它的多媒体指令集以及并行处理的特征,使得优化DCT这样的模块有了更加灵活的发挥空间。本章主要研究从DM642的指令角度优化DCT函数的方法。
DM642是TI公司采用TI的第二代高级超长指令字结构(VelociTI),使得在一个指令周期能够并行处理多条指令,它有四个运算单元,分别为.L,.M,.S,.D,其中每个运算单元分A,B两区,可分别处理不同类型的运算,因此可以达到每个指令周期运行八条指令。它可在600MHz时钟频率下工作,按照每个指令周期可并行8条32bit指令来计算,它可达到4800MIPS的峰值计算速度。DM642采用两级缓存结构第一级包括相互独立的LIP(16kB)和LID(16kB),只能作为高速缓存使用;第二级L2(256kB)是一个统一的程序/数据空间,可整体作为SRAM映射到存储空间,也可整体作为第二级Cache,或是二者按比例的一种组合来使用。因此若能合理使用和管理内存以及运算单元的最大化利用,将能大幅度提高程序的运行性能。
存在胜于数字视频通信和存储的各种应用,且已开发出并正在持续开发相应的国际标准。例如视频电话和会议的低位速率通信以及例如动画的较大视频文件压缩产生各种视频压缩标准H.261、H.263、MPEG-1、MPEG-2、AVS等。这些压缩方法依赖地离散余弦变换(DCT)或类似变换以及变换系数的量化来减少需用来编码的位的数目。
以下是二维DCT与IDCT的变换公式 二维DCT变换 令f(x,y)为N×N离散图像序列,二维DCT变换表示为 u,v=0,1,...N-1 二维IDCT为 x,y=0,1,...N-1 从公式中可以看出,DCT算法中存在大量的数据读写和加减法运算,就拿一个4x4dct来说,其中的加减法运算达到64次。并且在计算DCT的过程中,需要频繁的存取数据,一次4x4dct需要分别存取数据32次。导致大量的cpu cycle在等待存取数据的完成,使得该运算效率低下 void dct4x4(int16_t dct[4][4],uint8_t*pix1,uint8_t*pix2) { for(i=0;i<4;i++) { const int s03=d[i]
+d[i][3]; const int s12=d[i][1]+d[i][2]; const int d03=d[i]
-d[i][3]; const int d12=d[i][1]-d[i][2]; tmp
[i]=s03+s12; tmp[1][i]=2*d03+d12; tmp[2][i]=s03-s12; tmp[3][i]=d03-2*d12; } for(i=0;i<4;i++) {const int s03=tmp[i]
+tmp[i][3];const int s12=tmp[i][1]+tmp[i][2];const int d03=tmp[i]
-tmp[i][3];const int d12=tmp[i][1]-tmp[i][2];dct[i]
=s03+s12;dct[i][1]=2*d03+d12;dct[i][2]=s03-s12;dct[i][3]=d03-2*d12; } } 按照以上DCT的原始计算方法,每次读取16位的数据,对16位的数据进行加减运算。这样的话,就难以发挥DM642的特性,难以达到并行计算的目的,并且在等待存取数据的过程中,耗费了大量的cpu cycle(处理器周期),导致DCT运算成为H264编码中主要的瓶颈之一。
由于h264的实时编码要求,我们可以通过提升DCT模块的计算速度来达到提升整体编码性能的目的。
鉴于此,实有必要提出一种改进的技术方案以克服现有技术的缺陷。

发明内容
本发明提供一种基于DM642的二维DCT的优化方法,DM642是第二代高级超长指令字结构(VelociTI)的数字信号处理器,其特征在于通过两个指令ADD2和SUB2,它们是针对32位数据,分高低16位进行相加和相减运算,如使用ADD2指令时C=_add2(A,B),是将A与B的高16位相加,结果存放于C的高16位,将A与B的低16位相加,结果存放于C的低16位;使用SUB2指令时C=_sub2(A,B),是将A与B的高16位相减,结果存放于C的高16位,将A与B的低16位相减,结果存放于C的低16位。
优选地,所述DM642数字信号处理器在一个指令周期能够并行处理多条指令,它有四个运算单元,分别为.L,.M,.S,.D,其中每个运算单元分A,B两区,可分别处理不同类型的运算,因此可以达到每个指令周期运行八条指令。
优选地,ADD2和SUB2指令同时并行运用于.M,.L,.S,.D的八个运算单元。
优选地,其中改变程序的结构,主要是将矩阵进行转置,而转置通过SPACK2指令。
相对于现有技术,本发明方法在DCT计算的cpu cycle由原来的176降低到优化后的56,即提升了3倍多,提升效果显著。


无附图。
具体实施方式
对现有方法的改进在于,将循环展开,重新整理程序结构。DM642可以一次存取64位的数据。因此,展开后的程序,可以一次存读取64位的数据,使得存取的次数一次降低到了原来的1/4。
DM642有一系列类似于DOTPSU2这样的点积指令,它可以计算两个32位数据高低16位的乘加运算,比如C=_dotpsu2(A,B),是将A与B的高16位相乘,低16位相乘,相加的和赋给C。通过这条指令,可以将取得的32位数据的高低16位求和,而不用拆分,再计算。
使用类似DOTPSU2这样的指令,可以使用32位的数据,并且能够达到一定的并行目的,节省计算cpu cycle。但是由于DOTPSU2只能在CPU.M单元进行计算,即每个cpu cycle只能在A,B两个单元并行计算两次,没有充分发挥八个计算单元同时计算的目的,经过对程序的结构进一步优化和排序,我们找到了更加有用的方法。
这个方法是基于两个很简单的指令ADD2和SUB2,与原始运算不同的是,它们是对32位数据,分高低16位进行相加和相减运算。比如C=_add2(A,B),是将A与B的高16位相加,结果存放于C的高16位,将A与B的低16位相加,结果存放于C的低16位。并且它相对于DOTPSU2这个指令,有一个十分明显的优势,就是它不受限于在哪个计算单元运算,也就是说,它可以在cpu的.M,.L,.S,.D的八个运算单元同时进行运算。这样,就更加有利于提高程序的并行度。因此,使用ADD2和SUB2,而完全不用DOTPSU2,极大的压缩了cpucycle,即可以明显提升DCT计算速度。
以下为优化后的基于DM642的程序,其中改变程序的结构,主要是将矩阵转置,而转置只用了几个SPACK2打包指令。
void 4x4dct(uint8_t*p_dst,int16_t dct[4][4]) { int16_t d[4][4]; int16_t tmp[4][4]; int x,y; int i; int tmp0_10,tmp0_32,tmp1_10,tmp1_32; int tmp2_10,tmp2_32,tmp3_10,tmp3_32;int pack0_10,pack1_10,pack0_32,pack1_32; int pack2_10,pack3_10,pack2_32,pack3_32; int pack3_10_r,pack3_32_r,pack1_10_r,pack1_32_r; int d0_10,d0_32,d1_10,d1_32,d2_10,d2_32,d3_10,d3_32; int dct0_32=_hi(_amemd8((void*)dct
)); int dct0_10=_lo(_amemd8((void*)dct
)); int dct1_32=_hi(_amemd8((void*)dct[1])); int dct1_10=_lo(_amemd8((void*)dct[1])); int dct2_32=_hi(_amemd8((void*)dct[2])); int dct2_10=_lo(_amemd8((void*)dct[2])); int dct3_32=_hi(_amemd8((void*)dct[3])); int dct3_10=_lo(_amemd8((void*)dct[3])); int h_dct3_32=_shr2(dct3_32,1); int h_dct3_10=_shr2(dct3_10,1); int h_dct1_32=_shr2(dct1_32,1); int h_dct1_10=_shr2(dct1_10,1); int add20_10=_add2(dct0_10,dct2_10); int add20_32=_add2(dct0_32,dct2_32); int sub20_10=_sub2(dct0_10,dct2_10); int sub20_32=_sub2(dct0_32,dct2_32); int add31_10=_add2(h_dct3_10,dct1_10); int add31_32=_add2(h_dct3_32,dct1_32); int sub13_10=_sub2(h_dct1_10,dct3_10); int sub13_32=_sub2(h_dct1_32,dct3_32); int round=32|(32<<16); tmp0_10=_add2(add20_10,add31_10); tmp0_32=_add2(add20_32,add31_32); tmp1_10=_add2(sub20_10,sub13_10); tmp1_32=_add2(sub20_32,sub13_32); tmp2_10=_sub2(sub20_10,sub13_10); tmp2_32=_sub2(sub20_32,sub13_32); tmp3_10=_sub2(add20_10,add31_10); tmp3_32=_sub2(add20_32,add31_32); pack0_10=_pack2(tmp1_10,tmp0_10); pack1_10=_packh2(tmp1_10,tmp0_10); pack0_32=_pack2(tmp3_10,tmp2_10); pack1_32=_packh2(tmp3_10,tmp2_10); pack2_10=_pack2(tmp1_32,tmp0_32); pack3_10=_packh2(tmp1_32,tmp0_32); pack2_32=_pack2(tmp3_32,tmp2_32); pack3_32=_packh2(tmp3_32,tmp2_32); pack3_10_r=_shr2(pack3_10,1); pack3_32_r=_shr2(pack3_32,1); pack1_10_r=_shr2(pack1_10,1); pack1_32_r=_shr2(pack1_32,1);add20_10=_add2(pack2_10,pack0_10);add20_32=_add2(pack2_32,pack0_32);add31_10=_add2(pack3_10_r,pack1_10); add31_32=_add2(pack3_32_r,pack1_32); sub20_10=_sub2(pack0_10,pack2_10); sub20_32=_sub2(pack0_32,pack2_32); sub13_10=_sub2(pack1_10_r,pack3_10); sub13_32=_sub2(pack1_32_r,pack3_32); d0_10=_shr2(_add2(_add2(add20_10,add31_10),round),6); d0_32=_shr2(_add2(_add2(add20_32,add31_32),round),6); d1_10=_shr2(_add2(_add2(sub20_10,sub13_10),round),6); d1_32=_shr2(_add2(_add2(sub20_32,sub13_32),round),6); d2_10=_shr2(_add2(_sub2(sub20_10,sub13_10),round),6); d2_32=_shr2(_add2(_sub2(sub20_32,sub13_32),round),6); d3_10=_shr2(_add2(_sub2(add20_10,add31_10),round),6); d3_32=_shr2(_add2(_sub2(add20_32,add31_32),round),6); {int dst32=_amem4((void*)p_dst); int p_dst10,p_dst32; p_dst10=_add2(d0_10,_unpklu4(dst32)); p_dst32=_add2(d0_32,_unpkhu4(dst32)); _amem4((void*)p_dst)=_spacku4(p_dst32,p_dst10); p_dst+=FDEC_STRIDE; dst32=_amem4((void*)p_dst); p_dst10=_add2(d1_10,_unpklu4(dst32)); p_dst32=_add2(d1_32,_unpkhu4(dst32)); _amem4((void*)p_dst)=_spacku4(p_dst32,p_dst10); p_dst+=FDEC_STRIDE; dst32=_amem4((void*)p_dst); p_dst10=_add2(d2_10,_unpklu4(dst32)); p_dst32=_add2(d2_32,_unpkhu4(dst32)); _amem4((void*)p_dst)=_spacku4(p_dst32,p_dst10); p_dst+=FDEC_STRIDE; dst32=_amem4((void*)p_dst); p_dst10=_add2(d3_10,_unpklu4(dst32)); p_dst32=_add2(d3_32,_unpkhu4(dst32)); _amem4((void*)p_dst)=_spacku4(p_dst32,p_dst10); p_dst+=FDEC_STRIDE; } } DCT计算的cpu cycle由原来的176降低到优化后的56,即效率提升了3倍多,提升效果显著。
在上述实施例中,仅对本发明进行了示范性描述,但是本领域技术人员在不脱离本发明所保护的范围和精神的情况下,可根据不同的实际需要设计出各种实施方式。
权利要求
1.一种基于DM642的二维DCT的优化方法,DM642是第二代高级超长指令字结构(VelociTI)的数字信号处理器,其特征在于通过两个并行运算指令ADD2和SUB2,它们是针对32位数据,分高低16位进行相加和相减运算,如使用ADD2指令时C=_add2(A,B),是将A与B的高16位相加,结果存放于C的高16位,将A与B的低16位相加,结果存放于C的低16位;使用SUB2指令时C=_sub2(A,B),是将A与B的高16位相减,结果存放于C的高16位,将A与B的低16位相减,结果存放于C的低16位。
2.如权利要求1所述的基于DM642的二维DCT的优化方法,其特征在于所述DM642数字信号处理器在一个指令周期能够并行处理多条指令,它有四个运算单元,分别为.L,.M,.S,.D,所述A、B为每个运算单元分A,B两区,可分别处理不同类型的运算,因此可以达到每个指令周期运行八条指令。
3.如权利要求2所述的基于DM642的二维DCT的优化方法,其特征在于ADD2以及SUB2指令同时并行运用于.M,.L,.S,.D的八个运算单元。
4.如权利要求1所述的基于DM642的二维DCT的优化方法,其特征在于其中改变程序的结构,主要是将矩阵进行转置,而转置通过打包指令SPACK2。
全文摘要
本发明涉及一种基于DM642的二维DCT的优化方法,DM642是第二代高级超长指令字结构(VelociTI)的数字信号处理器,通过两个指令ADD2和SUB2,它们是针对32位数据,分高低16位进行相加和相减运算,如使用ADD2指令时C=_add2(A,B),是将A与B的高16位相加,结果存放于C的高16位,将A与B的低16位相加,结果存放于C的低16位;使用SUB2指令时C=_sub2(A,B),是将A与B的高16位相减,结果存放于C的高16位,将A与B的低16位相减,结果存放于C的低16位。通过提升DCT变换的计算速度来达到提升整体编码性能的目的。
文档编号H04N7/30GK101610418SQ20091010868
公开日2009年12月23日 申请日期2009年7月14日 优先权日2009年7月14日
发明者军 喻 申请人:深圳市融创天下科技发展有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1