在TMS320C6x系列DSP上G.729A算法的优化
发布时间:2008/9/23 0:00:00 访问次数:858
语音通信是现代多媒体通信中一个重要的组成部分,语音压缩又是实现低速率语音通信的关键技术。国际电信联盟(itu)于1996年提出了一种共轭结构代数码激励线性预测(cs-acelp)的语音编码算法—g.729。该算法在8kbits码率下具有较好的语音编码质量,且延迟较短,因此在ip电话、移动通信、多媒体网络通信以及各种手持设备中具有广泛应用。g.729a是在g.729基础上进行了一部分简化,使得编码的复杂度降低,对硬件的要求更低,而编码质量并没有明显降低[1][2][3]。
2.g.729a的dsp软件开发流程
在编写和调试c6000程序时,为了使c6000代码获得最好的性能,我们需要按照软件编程的3个阶段进行,每个阶段完成的任务如下[4]:
第一阶段:开始可以不考虑c6000的有关知识,完全根据任务编写c语言程序。在ccs环境下用c6000的代码产生工具,编译产生在c6000内运行的代码,证明其功能正确。然后再用ccs的调试工具,如debug和profiler等,分析确定代码可能存在的、影响性能的低效率段。为进一步改进代码性能,需要进入第二阶段。
第二阶段:利用内联函数、ccs编译选项和其他具体优化方法改进c语言程序。重复第一阶段,检查所产生的c6000代码性能。如果产生的代码仍不能达到所期望的性能,则进入第三阶段。
第三阶段:从c语言程序中抽出对性能影响很大的程序段,用线性汇编重新编写,再用汇编优化器优化,链接,直到达到所期望的性能要求。
具体到g.729a标准编解码器的实时要求,第三阶段是工作的重点,而且线性汇编的重新编写要求对程序代码和dsp的特性有充分的了解。
3. g.729a代码的剖析
ccs集成开发环境为软件开发人员提供了高效的开发、调试工具。特别是它提供了评价器( profiler)的优化工具,通过收集在指定代码区间程序执行的统计性能,分析确定程序中各个段、各个子函数所花费的处理器时间,从而把程序的优化集中在对程序性能影响最大的代码段上去[5]。其两种不同的测试方法是:
(1) 在需要测定复杂度的程序段的开头和结尾处设定两个断点,打开时钟窗口,运行程序。在第一个断点处执行停止,这时双击时钟窗口使之清0,接着继续执行程序,在第二个断点处停止,这时,时钟窗口显示的值便是该段代码的复杂度。这在测试程序中一个函数的复杂度是非常有用的。
(2) 先打开统计窗口,在需要测试的程序段头尾设置统计点((probe point)。程序运行结束后,统计窗口内该程序段后面的统计值便是该代码段的复杂度。这种方法较简单,统计点自动收集统计信息,无需手工干涉,这在测定程序多段代码的复杂度是非常有用。
4. 线性汇编的优化
线性汇编是ti提供的一种汇编语言,其指令系统和汇编语言的指令系统完全相同,但在编写时不需要指定寄存器和操作单元,也不需要考虑延时的问题,因此编写线性汇编相对要容易一些 [6]。
经过第一阶段和第二阶段的优化后,音频编码程序在dm642上的运行状况有了很大改善,但是经测试仍然没有到达实时效果,而高级语言的效率几乎发挥到了极致,测试的速度达到了36.5帧/s,是未优化之前的10倍。这时,我们采用线性汇编语言重新编写c代码的低效率段程序,进一步提高程序的执行效率和充分利用dm642的硬件资源,最终按设计要求在dm642实时实现g.729a编码。在前面的dsp开发流程已经提过,dsp开发的最后一个手段是用汇编重写c代码,它是唯一可以既提高程序执行速度又可以减少程序体积的方法。由于针对并行处理器编写汇编的难度很大,一般采取的是混合编程的方法,即程序的主要部分用c代码,部分耗时较大的函数可以用线性汇编改写。
在编写线性汇编优化代码的过程中,为了提高代码执行效率,我们需要遵循以下原则[7]:
(1)写并行代码:通过使用汇编指令并行执行的方法减少循环内的执行周期数,优化线性汇编代码。这里的关键问题是弄清指令相关性,只有不相关的指令才能并行执行。辨别指令是否相关,可以使用相关图。
(2)处理跳转指令和转移指令:汇编程序的一大特点就是频繁地跳转,当满足不同的条件时,要求程序进行不同的操作,或跳到相应的位置。对于“大于”、“大于等于”、“小于”、“小于等于”等较为接近的逻辑判断和处理,应慎重对待,否则将产生逻辑性错误,并且很难调试。当发生溢出需进行相应处理时,这种现象尤为突出。
(3)尽量减少循环体内的指令数:g.729a的算法实现,有许多是在循环内部完成的,有些地方如固定码本搜索过程中,为了确定四个非0脉冲的位置和幅度,还用到了多重循环。在循环内部,特别是在嵌套较深的循环内部,减少一条指令可以大大降低程序的操作次数。例如,对于一个每重循环8次的四重嵌套循环,在最内层循环每减少一条指令,整个程序可以少执行84=4096语句。因此在设计程序时,能够放在循环体外执行的语句,尽量放在
语音通信是现代多媒体通信中一个重要的组成部分,语音压缩又是实现低速率语音通信的关键技术。国际电信联盟(itu)于1996年提出了一种共轭结构代数码激励线性预测(cs-acelp)的语音编码算法—g.729。该算法在8kbits码率下具有较好的语音编码质量,且延迟较短,因此在ip电话、移动通信、多媒体网络通信以及各种手持设备中具有广泛应用。g.729a是在g.729基础上进行了一部分简化,使得编码的复杂度降低,对硬件的要求更低,而编码质量并没有明显降低[1][2][3]。
2.g.729a的dsp软件开发流程
在编写和调试c6000程序时,为了使c6000代码获得最好的性能,我们需要按照软件编程的3个阶段进行,每个阶段完成的任务如下[4]:
第一阶段:开始可以不考虑c6000的有关知识,完全根据任务编写c语言程序。在ccs环境下用c6000的代码产生工具,编译产生在c6000内运行的代码,证明其功能正确。然后再用ccs的调试工具,如debug和profiler等,分析确定代码可能存在的、影响性能的低效率段。为进一步改进代码性能,需要进入第二阶段。
第二阶段:利用内联函数、ccs编译选项和其他具体优化方法改进c语言程序。重复第一阶段,检查所产生的c6000代码性能。如果产生的代码仍不能达到所期望的性能,则进入第三阶段。
第三阶段:从c语言程序中抽出对性能影响很大的程序段,用线性汇编重新编写,再用汇编优化器优化,链接,直到达到所期望的性能要求。
具体到g.729a标准编解码器的实时要求,第三阶段是工作的重点,而且线性汇编的重新编写要求对程序代码和dsp的特性有充分的了解。
3. g.729a代码的剖析
ccs集成开发环境为软件开发人员提供了高效的开发、调试工具。特别是它提供了评价器( profiler)的优化工具,通过收集在指定代码区间程序执行的统计性能,分析确定程序中各个段、各个子函数所花费的处理器时间,从而把程序的优化集中在对程序性能影响最大的代码段上去[5]。其两种不同的测试方法是:
(1) 在需要测定复杂度的程序段的开头和结尾处设定两个断点,打开时钟窗口,运行程序。在第一个断点处执行停止,这时双击时钟窗口使之清0,接着继续执行程序,在第二个断点处停止,这时,时钟窗口显示的值便是该段代码的复杂度。这在测试程序中一个函数的复杂度是非常有用的。
(2) 先打开统计窗口,在需要测试的程序段头尾设置统计点((probe point)。程序运行结束后,统计窗口内该程序段后面的统计值便是该代码段的复杂度。这种方法较简单,统计点自动收集统计信息,无需手工干涉,这在测定程序多段代码的复杂度是非常有用。
4. 线性汇编的优化
线性汇编是ti提供的一种汇编语言,其指令系统和汇编语言的指令系统完全相同,但在编写时不需要指定寄存器和操作单元,也不需要考虑延时的问题,因此编写线性汇编相对要容易一些 [6]。
经过第一阶段和第二阶段的优化后,音频编码程序在dm642上的运行状况有了很大改善,但是经测试仍然没有到达实时效果,而高级语言的效率几乎发挥到了极致,测试的速度达到了36.5帧/s,是未优化之前的10倍。这时,我们采用线性汇编语言重新编写c代码的低效率段程序,进一步提高程序的执行效率和充分利用dm642的硬件资源,最终按设计要求在dm642实时实现g.729a编码。在前面的dsp开发流程已经提过,dsp开发的最后一个手段是用汇编重写c代码,它是唯一可以既提高程序执行速度又可以减少程序体积的方法。由于针对并行处理器编写汇编的难度很大,一般采取的是混合编程的方法,即程序的主要部分用c代码,部分耗时较大的函数可以用线性汇编改写。
在编写线性汇编优化代码的过程中,为了提高代码执行效率,我们需要遵循以下原则[7]:
(1)写并行代码:通过使用汇编指令并行执行的方法减少循环内的执行周期数,优化线性汇编代码。这里的关键问题是弄清指令相关性,只有不相关的指令才能并行执行。辨别指令是否相关,可以使用相关图。
(2)处理跳转指令和转移指令:汇编程序的一大特点就是频繁地跳转,当满足不同的条件时,要求程序进行不同的操作,或跳到相应的位置。对于“大于”、“大于等于”、“小于”、“小于等于”等较为接近的逻辑判断和处理,应慎重对待,否则将产生逻辑性错误,并且很难调试。当发生溢出需进行相应处理时,这种现象尤为突出。
(3)尽量减少循环体内的指令数:g.729a的算法实现,有许多是在循环内部完成的,有些地方如固定码本搜索过程中,为了确定四个非0脉冲的位置和幅度,还用到了多重循环。在循环内部,特别是在嵌套较深的循环内部,减少一条指令可以大大降低程序的操作次数。例如,对于一个每重循环8次的四重嵌套循环,在最内层循环每减少一条指令,整个程序可以少执行84=4096语句。因此在设计程序时,能够放在循环体外执行的语句,尽量放在
上一篇:二维DCT编码的DSP实现与优化