TMS320C6000嵌入式系统优化编程的研究
时间:04-08
来源:互联网
点击:
2.1 使用汇编语言
使用汇编语言进行并行编程难度比较大。但在有些情况下,程序中数据有非常强的承接关系,并且该程序体逻辑关系清楚,使用的寄存器不超过32个, 这时直接使用汇编语言实现,效率会更高。另外,有些使用C语言比较难实现的运算函数,在C6000的汇编指令集中可能有专用DSP指令,这时就可以直接使用汇编语言实现。
使用汇编语言进行编程时特别需要注意的是C6000指令的延迟情况,有些指令并不是立刻就能得到结果。C6000指令集中有延迟的指令如表1所示。

例1 32位归一化函数norm_l()
short norm_l(long L_var1)
{short var_out;
if (L_var1 == 0L) {
var_out = (short)0;
}
else {
if (L_var1 == (long)0xffffffffL) {
var_out = (short)31;
}
else {
if (L_var1 < 0L) {
L_var1 = *L_var1;
}
for(var_out=(short)0;L_var1<(long)0x40000000L;
var_out++) {
L_var1 <<= 1L;
}}}
return(var_out);
}
使用汇编语言进行优化:
.global _norm_l
_norm_l:
B B3
CMPEQ 0,A4,B0
[!B0] NORM A4,A4
NOP 3
消耗时间(时钟周期):C语言norm_l()为723;汇编语言为11。
2.2 使用线性汇编语言重写整个函数
对于某些以循环体为主的函数可以使用线性汇编语言重写整个函数。使用汇编优化器进行优化之后,效率是非常高的。
下面例子是算法中计算帧能量的函数,其中包含两个单循环体。进行优化时,首先要确定循环的次数。对于循环次数是变量的情况,优化器不进行并行优化; 其次尽量减少数据存取次数,例如以32位存取指令对16位数据进行存取,可以节省一半的存取周期。仔细观察C代码,会发现两次循环次数相同。第二个循环要用到第一个循环的结果,因此可以将两个循环合并在一起,这样就避免了在第二个循环中再从存储器中取结果,减少了一半的Load操作。
long Comp_En( short *Dpnt)
{ int i ;
long Rez ;
short Temp[60] ;
for ( i = 0 ; i < 60 ; i ++)
Temp[ i] = shr( Dpnt[ i], (short) 2) ;
Rez=(long) 0 ;
for (i=0; i <60; i ++)
Rez=L_mac(Rez, Temp[ i], Temp[ i]);
return Rez ;
}
相应的线性汇编程序如下:
.global _Comp_En ;函数名定义,对c变量前加__Comp_En .cproc Dpnt;函数头定义,Dpnt是参数
.reg Rez,Rez1,Rez2,I ;寄存器定义,不必考虑实际的寄存器分配
.reg t1,t2,x1,c1,m1,m2
zero Rez
zero Rez1
zero Rez2
mv Dpnt,c1
mvk 30,i ;确定循环次数。因为用LDW代替LDH,循环次数减少一半。
loop1 .trip 30
ldw *c1++,x1
shl x1,16,t1
shr t1,2,t1
shr x1,2,t2 ;将两个循环合在一起,又减少了一半的从内存取数据的时间。
smpyh t1,t1,m1
smpyh t2,t2,m2
sadd Rez1,m1,Rez1
sadd Rez2,m2,Rez2
[ i] sub i,1,i ;循环计数器从30递减
[ i] b loop1
sadd Rez1,Rez2,Rez
.return Rez
.endproc
消耗时间(时钟周期):C语言为32971;线性汇编语言为93。
使用汇编语言进行并行编程难度比较大。但在有些情况下,程序中数据有非常强的承接关系,并且该程序体逻辑关系清楚,使用的寄存器不超过32个, 这时直接使用汇编语言实现,效率会更高。另外,有些使用C语言比较难实现的运算函数,在C6000的汇编指令集中可能有专用DSP指令,这时就可以直接使用汇编语言实现。
使用汇编语言进行编程时特别需要注意的是C6000指令的延迟情况,有些指令并不是立刻就能得到结果。C6000指令集中有延迟的指令如表1所示。

例1 32位归一化函数norm_l()
short norm_l(long L_var1)
{short var_out;
if (L_var1 == 0L) {
var_out = (short)0;
}
else {
if (L_var1 == (long)0xffffffffL) {
var_out = (short)31;
}
else {
if (L_var1 < 0L) {
L_var1 = *L_var1;
}
for(var_out=(short)0;L_var1<(long)0x40000000L;
var_out++) {
L_var1 <<= 1L;
}}}
return(var_out);
}
使用汇编语言进行优化:
.global _norm_l
_norm_l:
B B3
CMPEQ 0,A4,B0
[!B0] NORM A4,A4
NOP 3
消耗时间(时钟周期):C语言norm_l()为723;汇编语言为11。
2.2 使用线性汇编语言重写整个函数
对于某些以循环体为主的函数可以使用线性汇编语言重写整个函数。使用汇编优化器进行优化之后,效率是非常高的。
下面例子是算法中计算帧能量的函数,其中包含两个单循环体。进行优化时,首先要确定循环的次数。对于循环次数是变量的情况,优化器不进行并行优化; 其次尽量减少数据存取次数,例如以32位存取指令对16位数据进行存取,可以节省一半的存取周期。仔细观察C代码,会发现两次循环次数相同。第二个循环要用到第一个循环的结果,因此可以将两个循环合并在一起,这样就避免了在第二个循环中再从存储器中取结果,减少了一半的Load操作。
long Comp_En( short *Dpnt)
{ int i ;
long Rez ;
short Temp[60] ;
for ( i = 0 ; i < 60 ; i ++)
Temp[ i] = shr( Dpnt[ i], (short) 2) ;
Rez=(long) 0 ;
for (i=0; i <60; i ++)
Rez=L_mac(Rez, Temp[ i], Temp[ i]);
return Rez ;
}
相应的线性汇编程序如下:
.global _Comp_En ;函数名定义,对c变量前加__Comp_En .cproc Dpnt;函数头定义,Dpnt是参数
.reg Rez,Rez1,Rez2,I ;寄存器定义,不必考虑实际的寄存器分配
.reg t1,t2,x1,c1,m1,m2
zero Rez
zero Rez1
zero Rez2
mv Dpnt,c1
mvk 30,i ;确定循环次数。因为用LDW代替LDH,循环次数减少一半。
loop1 .trip 30
ldw *c1++,x1
shl x1,16,t1
shr t1,2,t1
shr x1,2,t2 ;将两个循环合在一起,又减少了一半的从内存取数据的时间。
smpyh t1,t1,m1
smpyh t2,t2,m2
sadd Rez1,m1,Rez1
sadd Rez2,m2,Rez2
[ i] sub i,1,i ;循环计数器从30递减
[ i] b loop1
sadd Rez1,Rez2,Rez
.return Rez
.endproc
消耗时间(时钟周期):C语言为32971;线性汇编语言为93。
- F1aSh存储器在TMS320C3X系统中的应用(11-11)
- 基于PIC18F系列单片机的嵌入式系统设计(11-19)
- DSP在卫星测控多波束系统中的应用(01-25)
- 基于PCI总线的双DSP系统及WDM驱动程序设计(01-26)
- 利用Virtex-5 FPGA实现更高性能的方法(03-08)
- DSP与单片机通信的多种方案设计(03-08)
