How to write C/C++ code in DSP? + Data types in c6000
[Copy link]
Question: How to write C/C++ code?
Data Types:
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
Based on the difference of each data type, we have the following guidelines when writing C code:
1: Avoid mixing int and long, because C6000 defines the value of long as 40 bits
2: Whenever possible, we should try to use short type data as the input of fixed-point multiplication, because
this data type is the most efficient for the C6000 multiplier. (short×short uses 1 clock cycle, int×int uses
5 clock cycles);
3: Use int or unsigned int type as loop counter instead of short or unsigned short data type
to avoid unnecessary sign extension instructions.
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: When using a C6400 device, use the –mv6400 compiler switch so the code generated will use the device's additional
hardware and instructions.
Analyzing the Performance of C Code
Use the following statistics to analyze the performance of a particular code:
1: A preliminary approach is to look at the running time of the code. Use the clock() and printf() functions to calculate the time and display
it. We can use software simulation alone to achieve our goal. Remember to subtract the time of the call to the clock() function.
2: Use the profile mode of the software simulation. This can be done by compiling our code with the -mg option and executing load64x with
the -g option. The results of the profile are stored in a file (with a .vaa type extension) - 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: The most critical section of our code is often the loop section. The easiest way to optimize the loop is to break the loop
into a separate file that can be rewritten, recompiled and simulated with the software simulator.
Example 2–5. Including the clock( ) Function
#include <stdio.h>
#include <time.h> /* 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\n”, stop – start – overhead);
start = clock();
vec_mpy1(y, x, scalar);
stop = clock();
printf(”vec_mpy1 cycles: %d\n”, stop – start – over head);
start = clock();
iir1(coefs, x, optr, state);
stop = clock();
printf(”iir1 cycles: %d\n”, 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)
Use inline functions:
such as: 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);
}
You can use: result = _sadd(a,b);
Inline function table:
Use of DATA_SECTION pragma:
This object refers to a far variable, and this variable cannot be overwritten. If we refer to this variable in another file
, we must declare it: use extern far. This protects the reading of the variable, because this variable may not be in the .bss section.
|