一、编程优化
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优化