DSP

DSP中如何写C/C++代码? + c6000中数据类型

2019-07-13 10:56发布

[DSP(TI)]DSP中如何写C/C++代码?
耿磊 发表于 2005/6/27 20:51:51 http://blog.gkong.com/more.asp?name=barongeng&id=726
这个博客有不少好东西,大家有空可以看看。 问题的提出:如何写C/C++代码?
  1. 数据类型:
    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编译器开关,这样代码的产生就会使用设备额外的
       硬件和指令。
  2. 分析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:我们代码中最关键的部分往往是循环部分。优化循环最简单的办法是把这个循环分解
       成单独的可以重写的,重编译的可以用软件仿真器仿真的文件。
  3. 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);
    }
  4. 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)
  5. 使用内联函数:
    如: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);
    内联函数表:
  6. DATA_SECTION pragma的使用:
    这个对象指出的是一个far变量,并且这个变量不能被覆盖。要是我们在另一个文件中涉及这个变量
    那么我们必须声明一下:用extern far。这样做保护变量的读取,因为这个变量可能不在.bss段中。