3.2.3 内联函数优化
通过下面的方法改进C语言程序,可使编译出的代码性能显著提高:
(1)使用intrinsics(内联函数)替代复杂的C/C++代码;
(2)使用字(Word)访问存放在32位寄存器的高16位和低16位字段的数据;
(3)使用双字访问存放在64位寄存器的32位数据(仅指C64xx/C67XX)。
C6000编译器提供了许多内联函数,它们直接对应着C62X/C64X/C67X指令可快速优化C代码。这些内联函数不易用C/C++语言实现其功能。内联函数用前下划线“_”特别标示,其使用方法与调用函数一样。例如C语言的饱和加法只能写为需要多周期的函数:
这段复杂的代码可以用_sadd()内联函数实现,它是一个单周期的C6x指令。
result=_sadd(a,b);
要提高C6000数据处理率,应使一条Load/Store指令能访问多个数据。C6000有与内联函数相关的指令,例如_add2(),_mpyhl(),_mpylh()等,这些操作数以16位数据形式存储在32位寄存器的高位部分和低位部分。当程序需要对一连串短型数据进行操作时,可使用字1次访问2个短型数据,然后使用C6000相应指令来处理数据。相似的在C64x或C67x中,有时需要执行64位的LDDW来访问两个32位数据,4个16位数据,甚至8个8位数据。
3.2.4 循环展开
循环展开是改进性能的另一种,即把小循环的迭代展开,以让循环的每次迭代出现在代码中。这种方法可增加并行执行的指令数。当每次迭代操作没有充分利用C6000结构的所有资源时,可使用循环展开提高性能。
有3种使循环展开的方法:
(1)编译器自动执行循环展开;
(2)在程序中使用UNROLL伪指令建议编译器做循环展开;
(3)用户自己在C/C++代码中展开。
3.3 汇编优化
在对C/C++代码使用了所有的C/C++优化手段之后,如果仍然不满意代码的性能,就可以写线性汇编程序,然后用汇编优化器进行优化,生成高性能的代码。
3.3.1 写线性汇编
使用C6000的剖析工具(Profiling Tools)可以找到代码中最耗费时间的部分,就是这部分需要用线性汇编重写。线性汇编代码与汇编源代码相似,但是,线性汇编代码中没有指令延迟和寄存器使用信息。这样做的目的是由汇编优化器来为自己设定这些信息。
写线性汇编代码时,需要知道:汇编优化器伪指令、影响汇编优化器行为的选项、TMS320C6000指令、线性汇编源语句语法、指定寄存器或寄存器组、指定功能单元、源代码注释等。
3.3.2 汇编优化器优化
汇编优化器的任务主要有:
(1)编排指令,最大限度的利用C6000的并行能力;
(2)确保指令满足C6000的延迟要求(Latency Requirements);
(3)为源代码分配寄存器。
4 结 语
C6000系列的DSP C/c++代码优化比传统的代码优化要方便的多,但要真正发挥其芯片的工作效率还是需要一定的经验和技巧。这不仅要求开发人员熟悉其硬件体系,还要求对编译器的编译原理有一定的理解。另外,在C语言层面上要达到DSP芯片的峰值即8条指令并行是很难的,大多情况下都只能达到6.7条指令并行。在实际开发中,若优化结果已达到6,7条指令并行却还离实时的要求相差很远,再花大量的人力去力求达到8条指令并行是不经济的,此时应该考虑其他的技术改进或策略上的调整以求达到目的。