基于TI_C6000_DSP的C_C++语言代码效率优化

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Abstract:In the DSPs project,the C code optimization is very important.This paper illustrates the method to reach hi【gh performance
fbf TI C6000 DSPs accordiIlg to C6000 DSPs’unique h盯dware structure.Then analyze the result of the optimization.At last,this pa-
时间。再次修改如下:
void funl(n。at宰陀strict。utput,float}restrict input,float宰I restrict preArray)
万方数据
5期
刁一平等:基于TI C6000 DSP的C/C++语言代码效率优化
547

register int i; register float col=alphas;
图1软件流水线结构
万方数据
微计算机应用
2007年
6 实现高质量流水线的方法
流水线的质量体现在指令的并行度上。其并行度越高,程序 执行所需的时间也就越短,C6000的峰值是达到8条指令的并行。修改编译器(complier)的设置,选中如下 几个选项:
一03——表示最高程度的优化,编译器将执行各种优化循环的方法,如软件流水、循环展开。 一pm——在使用一03选项进行优化时尽量联合使用一pm选项,一pm是程序级优化,使优化器访问整 个程序,了解循环次数。 一叩3——通知编译器会用到其他文件中定义的函数,但不用其他文件中所定义的变量。
一般传统嵌入式系统开发项目分为三个阶段‘3|:①c代码开发阶段;②c代码优化阶段;③手工汇编代
本文于2006—10一10收到。
万方数据
5期
刁一平等:基于n C6000 DSP的C/C++语言代码效率优化
545
码重编写阶段。 第一阶段编写的c代码以程序编写调试为主要目的,为了便于调试更注重的代码的阅读性,忽视运行
TMS320 C6000通用数字信号器是,11公司推出的一种并行处理的数字,其具体的硬件结构可以参见参 考文献[2]。
C6000的结构基于超长指令字结构(VLIW)。在CPU内核(core)有8个并行独立的处理单元:.Ll、. S1、.M1、.D1和.匕、.s2、.MY.、.D2,以及两组独立的寄存器组。每个单元完成一定的算术和逻辑运算。由 于这些独立的并行处理单元,理论上最大可以8条指令同时运行。相当于8个传统的CPU(只有一个处理单 元)并行工作。 3 C6000算法实现及优化的流程
化主要依靠手工编写汇编指令实现,而TI(Texas Instruments)C6000系列DSP由于其特殊的硬件结构,可以 直接在c语言的层面上进行代码的优化就能达到十几,甚至几十倍的速度提升,这使得大部分的C6000 DSP 的开发在C语言优化阶段就能达到实时的要求。本文从C6000的硬件结构展开,讨论其优化的原理、方法 和策略。 2理器结构简介
t2=(·8-D;
tl幸=col; t2·=c02;
·8=tl+t2;
8++:
pre s*; s-f*; }
可以看到,重写的函数中新增加了许多寄存器变量来存放常用系数。在循环体的运算中减少了对内存
的访问次数,减少了CPU的等待时间。
在loop kernel中得到的最大并行指令如下:
[A2]
SUB
.S1
;132l<2,9>‘
从反馈信息中可见编译器自动优化的效果是实现了4条指令并行,用profiler测试,得到的结果为7699
个CPU cycle。要得到更高的指令并行度,需要对程序本身再进行修改。
因为C6000有相当丰富的寄存器组,可以利用寄存器变量(register variable)减少CPU对存储器的等待
C Code Optimization for TI C6000 DSPs
DIAO Yiping,ZHAO Xiaoqun (College of Electronics and Infuriation Engineering Tongji University,Shanghai,200092,China)
第28卷第5期 2007年5月
微计算机应用
MICROCOMPUTER APPLICATIONS
V01.28 No.5 May.2007
基于TI C6000 DSP的C/C++语言代码效率优化
刁一平 赵晓群
(同济大学电信学院上海200092)
摘要:在DSP项目开发中,代码优化是非常重要的环节。本文针对,11公司C6000系列DSP处理芯片的结构特点,阐述了基 于C6000硬件结构特点的C语言高效优化方法的原理,提出了展开复杂表达式以达到多指令并行的优化方法,并对其效果进 行了对比分析。对语音增强算法项目中所用的一些实际的经验和技巧进行了概括和总结。 关键词:DSP并行执行软件流水线循环展开


^。

阐述。
E2
D3
C4
B5
假设一个循环里有五条指令A、B、C、D、E。在图l中,阴影
部分是循环的核心,五条指令在同一时间执行。循环核心区之前
E3
D4
C5
为循环流水展开(pipelined—loop prolog),在后则是循环流水收
E4
D5
尾(pipelined—loop epilog)。
E5
4数字信号处理算法的特点
在数字信号处理中,存在着大量的乘加运算和迭代运算,即运算当前输出帧往往需要前输入和后输入 帧的内容,以下是一个语音增强算法中的一个典型程序模块:
void funl(float掌output,float木input,float幸preArray) {int i;float木s_f堆8,掌pre_s;
一。一产生优化注释语句。
一mv——产生循环指令清单。 ”一mk——产生编译器意见文件。
后三个选项主要用于让编译器产生反馈信息(包含在工程文件中自动生成的.asm文件中),前三个选项 则是编译器的优化选项。C6000的C/C++编译器提供了大量的编译选项,供用户在编译时选择使用。这些 选项中部分会直接影响或控制编译器优化过程,除了上述选项外,编译器针对不同的需要还提供了其他许 多设置,详情请见参考文献[3]。
同时对程序修改如下:
void funl(float宰restrict output,float宰restrict input,float·
restrict preArray)
{.…...
#pragm MUST ITERATE(128,,2)
for(i=0;i<frameSize;i++) {.…··;} }
21倍,比初级优化的效果也提高了ll倍。
借助软件流水可以大幅度提高代码效率,但要实现流水对程序本身还是有一定的要求,下面列举了一
些常见的无法产生软件流水的情况:寄存器生命周期太长,超过一次循环的最小时间;循环函数内包含过于
复杂的结构体;循环体内有函数的调用;函数体内有跳转指令,比如break,以及if else的连用;一个函数的调

MPYSP MPYSP
.M1 .M2
A5,A0,A0 B4,B7,137
;186 l<3,5> ;J86I<3,5>
现在已经实现了7条指令并行,若要达到8条指令并行,即芯片的峰值效率,则需要手工进行汇编代码
重写。
用profile工具对代码进行测试比较,最终的优化结果为670个CPU cycle,速度比不优化的情况提升了
A2,1,A2
;<0,14>
ຫໍສະໝຸດ Baidu
0[A1] 0[!A2] 0[!A2]
SUB STW STW
.L1 .D1T1 .D2T2
A1,1,A1
A4,幸++A6(8) B8,宰++B6(8)
;<0,14> ;186I<0,14> ;186I<0,14>
II[BO]
SUB
.s2
B0,1,B0
;190l<2,8>

首先增加了restrict关键字。明确代码中不存在存储器相关性。因为当编译器无法肯定两个指针是否
指向同一存储区间时,编译器就采取保守态度,默认为两个指针会指向同一区间,在进行数据读取或存储时
就对所需数据逐一操作,假设CPU 1次可读或存4个数据,但在默认的模式下,需要进行4次操作,浪费3次
操作的时间。除了restrict的关键词,也可以用编译器中的一mt选项确定代码中无存储相关性。其次再用伪
编译器自动优化完成后看反馈的汇编信息,在loop kernel中看到最大的并行指令如下:
[B1]
SUB
.D2
B1,l,B1
;<0,37>
lI
STW
.D1T2
B8,半+All(4)
;132 I<0,37>‘

MVKL
.S2
0x3fe4cccc,B3
;132I<2,9>‘
I|
MVKL
.S1
0x3fd66666,A1
指令MUST_ITERATE()告诉编译器待优化的循环体循环次数为2的倍数,可进行2倍的循环展开,并且展
开后循环次数为128。在软件流水形成的过程中,一个很重要的概念是循环展开(unroll)。这样可以平衡两
组处理单元的工作以及充分利用线宽来读取或存储数据。关于循环展开以及功能单元工作分配的平衡的
具体内容可参看参考文献[4],这里不做赘述。以上两点是代码优化的基本要求。
register float c02=alpha_s2; register float tl,t2; float·s—f,|【8,幸pre s; s=output;sj=input;pre_s 2 preAn-ay; 卸m乎m MUST ITERATE(128,,2) for(i=O;i<frame,Size;i++) {tl=(宰pre s);
per introduce some practical skills in the project of speech enhancement. Keywords:DSP,Parallel instruction,Software pipeline
1 引言 代码优化是数字信号处理器‘11(DSP)软件开发中的关键环节。传统的嵌入式项目开发中,硬件级的优
效率。第二阶段以效率为目的对算法进行初级的简化,即算法级优化。在传统的开发方式中,这一阶段仍 然不关注具体的硬件平台。最后是手工汇编代码重编写阶段,与具体的硬件平台有着密切的联系,在此阶 段有着最大幅度的效率提高,是传统优化中的关键阶段。
但是在C6000嵌入式项目的开发中,最大幅度的效率提高是在第二阶段也就是C语言代码优化阶段中 完成,往往可以达到十几甚至于几十倍的提升效果,所以实际开发中很少需要进行第三阶段的开发,也就是 手工重写汇编代码的阶段。因为重写汇编代码后效率提升的幅度已经很小,且要耗费大量的开发成本。所 以C代码优化是TIC6000系列DSP代码优化的关键步骤。
output=alpha弗intput+alpha2书preArray
为了对优化效果进行对比,先用CCS中的剖析工具profiler对以上程序段funl进行效率分析,得到运行 时间为21039个CPU cycle。
以下将以此程序为例,提出了在C代码优化的一种简单而有效的方法。
5 C6000系列C语言优化的重点——软件流水
s=output;
s_f=input; pre_s 2 preArray;
f or(i=0;i<frameSize;i++) {宰8=(float)(alpha—s掌(宰pre—s)+alpha—s2木
掌S
p掣=
8.,
其中,preArray是前一帧的output的值,frameSize是帧长,预定义为256,alpha和alpha7.是预定义的常 量系数。这段程序的作用是根据当前输入帧和前一输出帧计算当前的输出帧,数学公式如下:
用的寄存器组的数量超过寄存器组的数量;如果有循环嵌套,除了最内层循环体,其他循环体都不能产生软
件流水。
若在程序中出现在上述情况,则无法产生软件流水,此时必须修改代码,下面列举了一些修改程序而实

现流水的策略与方法:
’在算法中存在的循环体会占到整个程序的大部分执行时间。 减少这些循环体的执行时间,对于优化的工作有及其重要的
Al
Bl
A2
意义。
Cl
B2
A3
若C6000内核中有8个功能单元同时处理指令,可缩短整个
Dl
C2
B3
A4
循环体的运行时间,这类似于流水线,称为软件流水,如图l w’”。7
;E1
D2
C3
B4
~%,?{
相关文档
最新文档