APP下载

MIPS指令集G.729算法优化

2013-08-22林善和

科技视界 2013年7期
关键词:累加器编解码流水线

林善和

(福建星网锐捷通讯股份有限公司,福建 福州 350002)

0 引言

G.729是目前比较优质的语音压缩算法,10ms的语音,80个采样点,可以压缩到10字节,算法中用到了大量的移位,点乘,饱和,取整的运算,使用普通的指令虽然可以实现功能,但是消耗过多的CPU资源,不实用。

早期的编解码算法一般都是通过外挂的DSP来实现,随着技术的进步,一般家庭网关SoC的CPU性能越来越高,从原来的100M到现在的400-600M甚至更高,同时CPU也增加了DSP增强的指令集,这样很多算法直接就可以用CPU来处理,无需外挂DSP或者嵌一个DSP内核。

RT305x使用MIPS32 24KE的核心,内涵DSP ASE指令集,可以在一条指令完成2个short型数据的移位,4个short型数据的两两点乘相加,同时还顺便进行饱和,取整运算。

如果G729编解码算法运行时能够把CPU的占有率控制在30%以内,那么CPU还有足够的资源实现其它功能。因此,优化的目标就是在G729编解码时,RT305x的CPU占有率控制在30%以内。本文所阐述的优化是指对用标准C语言编写的代码用DSP增强指令集进行优化。

1 G.729AB优化步骤

1.1 准备一个30秒以上的PCM源文件,要求采样率8K,16位采样

1.2 编写g729_test.c和Make file,用来小工程编译G729

1.3 编译得到可执行文件,例如g729

1.4 把可执行文件g729及PCM的源文件复制到NFS目录

1.5 在设备上执行./g729 xx.pcm xx.g729,可以得到编码后的g729文件和再解码的pcm文件,还有完成编解码所需要的总时间

1.6 修改源码重新编译,再次运行,如果输出文件与之前的相同,而且消耗时间更短,则修改有意义

1.7 如果发现输出文件与之前不同,有可能是修改内容有问题。但是如果修改内容涉及到算法的优化,例如使用了64位的累加器,精度提高了,运算结果肯定与之前的不同,这是容许的,这时,用Cooledit打开输出的pcm文件,仔细查看,波形有没有变形,音质有没有变差

2 重点优化内容

2.1 基本元操作的优化

修改的内容在basic_op.c和basic_op.h中。

2.1.1 首先是用宏汇编指令代替函数的调用,要求是执行时间最短

2.1.2 很多的移位操作,需要判断移位的方向和次数,如果移位次数是常数,可以使用不带V的指令,例如用SRA代替SRAV

2.2 32位的常用运算的优化

内容在oper_32b.c和oper_32b.h,主要是32位的点乘运算,由于原始代码是多个平台公用,没有通用的点乘指令,所以点乘是由多个16位的数之间相乘,左移,再相加。在本平台的指令系统中,有专门的点乘指令,这是好东西,还可以提升运算的精度,不要放过。

2.3 乘加运算的集中优化

在编解码中,有许多地方用到了两个组数的点乘相加,通过for循环来完成,这个不断的点乘,不断的相加,在本平台,可以用乘加指令来完成,只需要在循环开始时清空64位累加器,循环结束之后,根据需要,移位相应的次数,把数据用64位累加器中取出,即可。

在点乘算法中,两个16位的数组两两点乘,首地址是4字节对齐,数组长度是偶数,我们同时把连续的两个16位数按照32位数载入寄存器,一起进行点乘运算,可以使循环次数减半。

在不少的算法中,由于担心乘加的数据会溢出,先把原始数据集体右移了几位,再点乘相加,为了保证精度,运算结果可能还左移了几位,对于这种情况,我们不需要先把数据集体右移,而是直接点乘,然后再取出数据时,再右移,保证运算结果不溢出,这个优化属于算法的优化,不仅省力,精度还更高。

2.4 循环的展开

在循环中,如果数据量比较大,循环的次数是比较多的,每次循环,开销至少需要3条指令(i++,判断,跳转),而且使得流水线中断。如果每次循环所干的事情多一些,循环的次数就会大大减少。

在从数组取出数据的时候,如果偏移地址是变量,会引入加法运算,聪明的做法是用x[0],x[1],x[-1]这种固定偏移的方式取数据,循环结束后修改x的值,代替用x[i]来访问内容,i++这种循环,循环的判断也不用i,而是直接判断数据的地址是否到达末地址。

在本平台的指令系统中,一条指令不能做到判断大于或小于非零而跳转,只能判断不相等,或大于或等于0而跳转,所以,把for(i=0;i<j;i++)写成for(i=0;i!=j;i++),会省一条指令。

如果i是short型,而j是常数或int型,在判断之前,会把i进行一次符号扩展。多一条指令,所以,在定义i的时候,建议保证待比较的两个变量,位宽一致。

2.5 流水线优化

MIPS32 CPU号称大部分指令是单周期指令,但实际上,单单一条指令上来看,一条指令包括,取指令,取操作数,执行,存储运算结果等几个,各需要一个指令周期,但是这些指令周期可以叠加,如果流水线不间断的运行,相当于一条指令只需要一个指令周期。

打断流水线,会引入额外的等待,本条指令使用上一条指令的运算结果,判断跳转指令,都会导致流水线的中断。

在纯C的代码中,编译器会自动优化流水线,但是,当嵌入汇编时,如果加了volatile属性,或者源操作数和目的操作数是隐含的,或者和内存交互数据,编译器是不会帮助优化流水线的,这时需要通过反汇编自己调整流水线。

为了使流水线不中断,通常的做法是本条指令的目的操作数,不要马上作为下一条指令的源操作数,而是间隔2条或2条指令以上。

对于跳转指令,由于流水线的缘故,该指令的下一条指令也会被执行到。这是特别需要注意的。

2.6 减少访问内存的次数

访问内存是比较慢的,如果没有Cache,访问一次内存大约需要100ns,CPU内有24个通用可用的寄存器,在函数调用时,4个及以内的形参传递,返回值,都不需要入栈。

在运行过程中,应尽量减少内存的访问次数,比如一次载入32bit数据,而不是分两次载入16bit的数据。

2.7 C内嵌汇编的实例

其中mult dpaq_sa.l.w mfhi是3条指令,$ac0是64位累加器,$zero是 0 寄存器,%0,%1,%2 的意思是用“:”后面的操作数代替,第一个”:”后面是目前操作数,第二个”:”的后面是源操作数,”=r”的意思是目的操作数,且为寄存器,”r”的意思是源操作数,且为寄存器,与内容交互数据的指令,可以用”m”。

2.8 DSP常用的运算结果处理

2.8.1 饱和

饱和处理就是运算结果限制在固定的位宽所能表示的数的范围,例如short型的最大数为0x7fff,最小数为0x8000,如果运算结果超出了这个范围,就根据正负,调整为0x7fff或0x8000,普通CPU的累加器没有对运算结果进行饱和处理,因此需要额外判断结果,再调整,DSP的累加器一般都能对运算结果饱和处理。一般同符号数的加法,不同符号的减法,点乘,左移,甚至取负,均有可能溢出。

2.8.2 取整

取整是在右移的操作中比较常用,右移会导致精度的丢失,根据移走的最高位,调整结果,有助于保留精度。

2.8.3 点乘

在物理上,点乘是已知力和位移求功。在数字信号处理中,这里的点乘其实是信号的相乘,信号幅度用小数表示,在本平台,用Q15(Word16)或 Q31(Word32)表示,两个 Q15 点乘,结果 Q31,但是直接数学相乘,只得到Q30,所以还需要左移一位。

3 优化结果分析

3.1 用标准C语言进行编解码算法测试CPU的占用率达到55%,无法满足实际应用需求。

3.2 反汇编

3.2.1 局部优化之后,用反汇编objdump-d来查看汇编代码,看看是否能得到预料中汇编代码,注意从内存中载入short型数据,带符号和不带符号,在扩展到32bit时,是不一样的

3.2.2 看看编译器是不是引入额外的指令,比如没有必要的符号扩展

3.2.3 看看流水线是否最佳

3.3 编解码的输出文件检验

得到的g729文件和PCM文件,首先是查看二进制是否和修改之前相同,如果不同,需要找到原因,如果是算法的优化导致的不同,需仔细查看声音有没有失真。最后用Abacus检测音质,同时进行长时间通话拷机。优化后的CPU占有率仅达30%。

4 结束语

在低成本家庭网关SoC芯片RT305x上使用MIPS32Kec带的DSP AE指令集进行G729编码的进行优化后,CPU占用率不到30%,满足家庭网关在语音、数据、Wifi的需求。随着CPU性能的越来越强以及通信网络IP话,这样的技术将在各种各样终端上使用,具有广泛的应用场景。

[1]王洪,唐凯.低速率语音编码 Low Rate Speech Coding[M].北京:国防工业出版社,2006.

[2]Chinh Tran Chijioke Anyanwu,Sanjai Balakrishnan,Anshul Bhargava,James Jiang,Radhika Thekkath.The24KETMCore Family:High-Performance RISC Cores with DSP Enhancements[M].MIPS Technologies Inc.,2005.

[3]MIPS Technologies Inc.MIPS DSP ASE Instruction Set Quick Reference.MIPS Technologies Inc.,2005.

猜你喜欢

累加器编解码流水线
Gen Z Migrant Workers Are Leaving the Assembly Line
密码累加器研究进展及应用
1553B总线控制器编解码设计
流水线
大型民机试飞遥测视频编解码方法研究
基于H.265编解码的高清视频传输系统研究
Fpga的信号发生器设计原理
报废汽车拆解半自动流水线研究
用于时间延迟积分型图像传感器的流水采样列级运放共享累加器*
SIMATIC IPC3000 SMART在汽车流水线领域的应用