![]() |
|
||||||||||||||
| . 网站首页 . 新闻 . 新品 . 方案 . 专访 . 活动 . DSP . EDA . 评测 . 技术文库 . 会员区 . 商城 . 服务导航 . 邮购 . 资源 . 社区 . | ||
|
||
|
|||||
| C代码在TMS320C54X上的手工汇编优化 | |||||
作者:钱俊 王芙… 文章来源:今日电子 点击数: 更新时间:2008-6-6 ![]() |
|||||
|
随着DSP技术的不断发展和完善,数字信号处理的应用范围越来越广泛。工控、计算机、通信和消费电子产品中,都会找到它的影子。近年来,随着多媒体通信的蓬勃发展,DSP也越来越多的应用在多媒体通信中,而在多媒体通信中DSP多用于语音压缩和图像处理等方面,而这些都需要巨大的计算量,在实时通信中一些低速DSP难以满足要求,而使用高速DSP会大大提高成本,所以对代码进行优化是现在DSP开发中常用的一种方法。由于DSP的特殊结构,编译器的编译效率都比较低,难以将DSP计算能力全部发挥出来,所以就必须根据DSP的特殊结构和指令集代码进行手工的汇编优化。 本文结合笔者在TI公司的TMS320VC5402 DSP上的对G.729算法的优化经验,提出一些优化的方法和建议,而这些方法也适用其他54系列的DSP。 2 芯片介绍 TMS320C54X是TI公司于1996年推出的新一代定点数字处理器,它具有功耗小、高度并行等优点,可以满足电信等众多领域的实时处理要求。54系列有很多不同型号的芯片,它们的结构都是一样的,只是在接口和存储器空间上有些不同。在54系列众多DSP芯片中 TMS320VC5402是使用最广泛的一种芯片,接下来将以TMS320VC5402为例介绍54系列DSP的性能特点: ● 运算速度最高达100MIPS ● 具有先进的多总线结构,三条16 位数据存储器总线和一条程序存储器总线 ● 40位算术逻辑单元(ALU),包括一个40位桶形移位器和两个40位累加器 ● 一个17bit×17bit乘法器和40位专用加法器,允许16位带/不带符号乘法 ● 8个辅助寄存器和一个软件栈 ● 内部采用改进的哈佛结构,程序空间和数据空间分开,允许同时取指令和取操作数,并且允许在程序和数据空间相互传送数据 ● 最大64K×16bit外部数据空间,最大1M×16bit外部程序空间,4K×16bit片内ROM,16K×16bit片内RAM ● 内置可编程等待状态发生器、锁相环(PLL)时钟发生器、两个多通道缓冲串口、一个8位并行与外部处理器通信的HPI口、两个16位定时器以及6通道DMA控制器 ● 支持单指令循环和块循环,采用六级流水线,将一条指令执行所需要的取指、译码、取操作数并执行等几个步骤同时完成,是指令周期降到最小适合算法的优化 3 代码优化 对C代码进行手工汇编优化有三种方法:1.对照C代码写出汇编代码,这种方法优化的效率很高,但是开发难度很大特别是当代码量很大,结构很复杂时优化很容易出错;2.先用编译器产生汇编代码,然后改写汇编代码,这种方法优化的效率较低,因为框架被限定了,但是开发难度降低了,不容易出错。 由于现在常用的一些音频、图像处理算法都是结构很复杂的程序,所以建议使用第二种优化方法。 3.1产生汇编代码 TI公司为DSP开发者提供一套编译开发平台叫CCS (Code Composer Studio),该工具提供了编译器可以将C语言的程序编译为DSP的汇编语言程序,然后链接生成可以在DSP上执行的COFF格式的out文件。 ![]() 而CCS自身也提供优化器可对C代码进行优化,并产生汇编语言程序,具体过程如图1所示。 CCS提供了4级的文件优化方案,分别是O0、O1、O2、O3,以下具体说明 。 (1) O0 寄存器级别 ● 执行控制流程简化 ● 用寄存器分配变量 ● 执行交替循环 ● 排除未用的代码 ● 简化公式和表述 ● 扩大对内连函数的调用 (2) O1 局部级别 执行所有O0级别的优化,并且: ● 执行局部常量的传播 ● 排除未用的赋值 ● 排除局部共用表达式 (3) O2 函数级别 执行所有O1级别的优化,并且: ● 执行循环优化 ● 排除全局共用子表达式 ● 排除全局不用的赋值 ● 执行打开循环 (4) O3 文件级别 执行所有O1级别的优化,并且: ● 排除未被调用的函数 ● 简化返回值没被使用的函数 ● 让小函数变成内联调用 ● 保存函数说明,以便主函数被优化时知道被调用 函数的属性 ● 识别文件级别的变量的特性 在使用O3级别的优化时,还可以使用别的选项执行更细致的优化 ● OLN 得到标准库函数的文件 ● ONN 创造优化信息文件 ● PM 执行程序级别优化,编译多个源文件 而我们在做优化时,选的是O2级别的优化,因为使用O2级别优化后产生的汇编文件带有比较多的注释信息,比较容易看懂程序,建议对程序不太熟和对汇编语言不太熟练的人使用。 3.2手工汇编优化 因为汇编语言可读性很差,并且代码量很大,所以手工优化工作量很大,并且容易出错。为了确保优化不出错,我们就先制作一段测试序列即程序的输入,然后运行程序对其进行处理,生成一段正确的结果序列,检验手工优化是否正确就是用优化过的程序对相同的测试序列进行处理,比较生成的结果序列和正确的结果序列是否一样,一样的话就代表优化无误。不过测试序列要比较长,因为有的错误开始不会显现出来,只是慢慢累积,运行一段时间才会出现。 接下来,就开始手工优化的工作。下面就是我对手工优化的一些经验。 (1) 尽量少进行函数调用。因为进行函数调用的时候,要将PC压栈,还要将一些寄存器压栈,函数调用完后,还要出栈,这都是一些不必要的操作,所以一些小的函数,就不调用,而是直接写入主函数里,这样可以就可以减少那些压栈出栈的操作,提高速度。 (2) 优化循环时,尽量将一些操作放到循环外面去,减少操作的次数。例如一些赋值和初始化操作,可以提到循环外面去做,来提高速度。 (3) 去除一些冗余的赋值。编译器产生的代码有很多赋值,经常将一个值赋给寄存器,再赋给变量,这样就产生了冗余。 (4) 尽量使用RPT和RPTB来执行循环操作。在编译器产生的代码里很多循环操作是通过条件判别来实现的,这样就多了很多无用的判别代码,而54x的DSP芯片就提供专门的循环指令:RPT和RPTB。RPT的功能就是循环执行下一条指令,循环次数由RC寄存器的值决定,循环次数是RC寄存器的值加1,所以执行循环前要将循环次数减1赋给RC寄存器;RPTB是块循环指令,它的功能是循环执行一段指令,它的循环次数由BRC寄存器决定,循环次数是BRC的寄存器的值加1,所以使用前需将循环次数减1赋给BRC寄存器。 (5) 使用比较快的寻址方式。在数字信号处理里面,会对大量的数据进行大量的运算,如果使用比较快的寻址方式会大大减少指令周期。因为数据大多是顺序存放,所以我们用寄存器去寻址,操作完后自加1而指向下个数据,这样寻址会减少很多指令周期。 (6) 使用循环缓冲区。因为FFT,FIR等常用运算中都需要对数据进行移位操作,如果数据量大的话,程序花在数据移位上的开销就很大了,如果使用循环缓冲区就可以不进行这些操作从而提高速度。 (7) 使用一些专用指令。在54的指令系统里,有一些专用指令执行一些特殊的操作,例如平方,FIR等,如果用其他指令代替需要多个指令周期,而使用专用指令值需要一个指令周期。 (8) 使用并行指令。因为DSP的流水线结构,可以让一些指令同时运行,就产生了并行指令,使用并行指令会大大减少指令周期。 |
|||||
| 欢迎点击进入:TI德州中文网 (国内唯一针对TI应用的中文技术网站) 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 没有相关文章 |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|