DSP

DSP编程优化总结

2019-07-13 16:14发布

一、编程优化

1、双重循环、多重循环优化

(1)多重循环拆成单层循环,减少循环层数;         例如,双重循环内一个cycle只使用了一个乘法器,拆成单层循环后,一个cycle可使用2个乘法器,充分利用DSP乘法器资源,同时运算速度也会加快; (2)循环次数少的放在外层循环,循环次数多的放在内存循环; (3)二维数组的二重循环:二维数组的行循环放在外层循环,列循环放在内层循环; (4)避免循环内部的乘除运算:循环内部的乘除运算尽量移到循环外部以及用加法替代;

2、内存操作函数

(1)内存拷贝:memcpy memcpy(Array_dst,Array_src,sizeof(Array_src));
  • 内存拷贝前需要对源地址和目的地址做内存对齐操作 :
#pragma DATA_ALIGN(Array, 8);             // 8字节对齐(低3位全为0)
  • 实际编程中应减少memcpy的操作次数,尽量使用指针进行内存搬移等操作。
  • 类似内存拷贝函数
void DSPF_sp_blk_move(const float * x, float *restrict y, const int n);
(2)内存清零:memset ​memset(Array,0,sizeof(Array));
注意:内存清零并不多余,因为某些编译器在分配空间时,内存默认值并不为0;此外,memset 函数只能用于赋0值,其他的值则会出错。
3、  

4、其他

(1)printf 等调试函数   printf 函数或其它调试函数的占用时间为ms级,且具备最高的系统优先级,不响应中断,对于代码运行有严重影响,且占用大量时间,调试时应去除此类函数。 (2)移位运算代替乘除运算
  • 乘除运算的指令执行时间要远远超过逻辑移位运算的执行时间;
  • 乘除运算尽量使用移位运算;
  • 不使用移位运算,也要将除法运算转化为乘法运算;
                     

【程序运行时间测试】

1、profile clock工具 (1)依次选择 Run—>Clock—>Enable; (2)Run—>Clock—>Setup(手动/自动清零); (3)双击右下角时钟周期计数栏(CPU cycle count)清零; (4)在程序之间设置断点,运行至第一个断点,清零,运行至第二个断点,记录CPU cycle count值; (5)程序运行时间:duration = CPU cycle count*(1/CPU_CLK);
缺点:时钟计数 cycle count 数据不准确,比实际情况的要大。  
2、TSCL、TSCH寄存器 #include unsigned int CycleOverHead; // 启动仿真性能计数 long long tBefore, tAfter,tOverhead; TSCL = 0; TSCH = 0; tBefore = _itoll(TSCH, TSCL); tAfter = _itoll(TSCH, TSCL); CycleOverHead = tAfter - tBefore; //寄存器读取延时校准 tBefore = _itoll(TSCH, TSCL); delay(10); tAfter = _itoll(TSCH, TSCL); tOverhead = tAfter - tBefore - CycleOverHead; printf("duration is %lld us (CPU Frequency:300MHz) ", tOverhead/300);   3、硬件测试方法 (1)在待测程序前加LED点亮程序,在待测程序后加LED灯灭程序; (2)运行程序,使用示波器测量LED引脚的电平变化,通过示波器的周期测量或者利用光标来测量待测程序时间;    

 

【CCS编译器优化】

 

二、Cache优化