[DSP(TI)]DSP中如何写C/C++代码?耿磊 发表于 2005/6/27 20:51:51
http://blog.gkong.com/more.asp?name=barongeng&id=726
这个博客有不少好东西,大家有空可以看看。
问题的提出:如何写C/C++代码?
-
数据类型:
C6000 compiler defines a size for each data type (signed and unsigned):
char 8 bits
short 16 bits
int 32 bits
long 40 bits
float 32 bits
double 64 bits
基于每种数据类型的不同,我们写C代码的时候,有如下的指导方针:
1:避免把int和long搞混,因为C6000把long的值定义为40位
2:无论在什么时间,我们都要尽量使用short类型的数据来作为定点乘法的输入,因为对C6000
的乘法器来说,这个数据类型最有效率。(short×short使用1个时钟周期,int×int使用
5个时钟周期);
3:使用int或unsigned int 类型作为循环计数器,而不是使用short或unsigned short数据类型
这样的目的是避免不必要的符号扩展指令。
4:When using floating-point instructions on a floating-point device such as
the ’C6700, use the –mv6700 compiler switch so the code generated will
use the device’s floating-point hardware instead of performing the task
with fixed point hardware. For example, the RTS floating-point multiply will
be used instead of the MPYSP instruction.
5:当使用C6400的设备时,使用-mv6400编译器开关,这样代码的产生就会使用设备额外的
硬件和指令。
-
分析C代码的性能
用以下的一些计数来分析指定代码的性能:
1:一个初步的手段是看看这段代码的运行时间。使用clock()和printf()函数来计算时间并显示
出来。我们可以单独使用软件仿真来实现我们的目标。记住要减去调用clock()函数的时间。
2:使用软件仿真的profile模式。这可以通过用-mg选项来编译我们的代码和执行load64x用
-g选项。profile的结果会存到一个文件中(带有.vaa类型扩展符)--TMS320C6000 Optimizing
C/C++ Compiler User’s Guide
3:Enable the clock and use profile points and the RUN command in the Code
Composer debugger to track the number of CPU clock cycles consumed
by a particular section of code. Use “View Statistics” to view the number
of cycles consumed.
4:我们代码中最关键的部分往往是循环部分。优化循环最简单的办法是把这个循环分解
成单独的可以重写的,重编译的可以用软件仿真器仿真的文件。
-
Example 2–5. Including the clock( ) Function
#include
#include /* need time.h in order to call clock()*/
main(int argc, char *argv[]) {
const short coefs[150];
short optr[150];
short state[2];
const short a[150];
const short b[150];
int c = 0;
int dotp[1] = {0};
int sum= 0;
short y[150];
short scalar = 3345;
const short x[150];
clock_t start, stop, overhead;
start = clock(); /* Calculate overhead of calling clock*/
stop = clock(); /* and subtract this value from The results*/
overhead = stop – start;
start = clock();
sum = mac1(a, b, c, dotp);
stop = clock();
printf(”mac1 cycles: %d
”, stop – start – overhead);
start = clock();
vec_mpy1(y, x, scalar);
stop = clock();
printf(”vec_mpy1 cycles: %d
”, stop – start – over head);
start = clock();
iir1(coefs, x, optr, state);
stop = clock();
printf(”iir1 cycles: %d
”, stop – start – overhead);
}
-
Refining C/C++ Code
You can realize substantial gains from the performance of your C/C++ code
by refining your code in the following areas:
Using intrinsics to replace complicated C/C++ code
Using word access to operate on 16-bit data stored in the high and low
parts of a 32-bit register
Using double access to operate on 32-bit data stored in a 64-bit register
pair (C64x and C67x only)
-
使用内联函数:
如:int sadd(int a, int b)
{
int result;
result = a + b;
if (((a ^ b) & 0x80000000) == 0)
{
if ((result ^ a) & 0x80000000)
{
result = (a < 0) ? 0x80000000 : 0x7fffffff;
}
}
return (result);
}
可以用:result = _sadd(a,b);
内联函数表:
-
DATA_SECTION pragma的使用:
这个对象指出的是一个far变量,并且这个变量不能被覆盖。要是我们在另一个文件中涉及这个变量
那么我们必须声明一下:用extern far。这样做保护变量的读取,因为这个变量可能不在.bss段中。