| 
 1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:     (1)优化循环     for(i = 0;i < max;i ++)      {         for(j = 0; j < max; j ++)         {             float sum = 0.0;             for(k = 0; k < max; k ++)             {                 sum += input[i * max + k] * input[j * max + k];             }             cover[i * max + j] = sum / max;         }     }     实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:      7 17 27 37 
     17 43 69 95 
     27 69 111 153 
     37 95 153 211     图示: 
          原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。     算法优化后:     for(i = 0; i < max; i ++)     {         for(j = i; j < max; j ++)                  // 减少一半循环         {             float sum = 0.0;             for(k = 0; k < max; k ++)             {                 sum += input[i * max + k] * input[j * max + k];             }             cover[i * max + j] = sum / max;             if(i != j)                    // 可加可不加,消除中线上的重复赋值             {                 cover[j *max + i] = sum / max;       // 赋值给另半个矩阵             }         }     }     (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)     k = k -1;     if(k < -1)     {         k = -1;     }     原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。     优化后:     k = max(k-1, -1);     转换成汇编后:     R0 += -1;    // R0 == k;     R1 = -1;     R0 = MAX(R0, R1);     (3)for循环中的条件跳转     for     {         if{...}else{...}     }     原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。     优化后:     if     {         for{...}     }     else     {         for{...}     }     (4)使用断言指令来避免条件跳转     if(A)     {         X = exp1;      }     else     {         X = exp2;     }         原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。     优化后:     X = exp1;     if(!A)     {         X = exp2;     }     (5)除法(取模)操作     一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。     除数为2的N次方时可采用右移法。     如为提高性能,可采取查表的方式,这样会损失精度。     隐藏的除法:         for(i = start; i < finish; i += step)         此时编译器会looper = (finish - start) / step 得到次数。     巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)         if(x / y > a / b)         可转换为:         if(x * b > a * y)     (6)数据类型     对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。     对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)     做数字信号处理操作时,如FFT,16bit的操作是比较合适的。     要做控制类,条件跳转时,32bit的操作是比较合适的。     如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。     (7)Memory分配     将运算比较频繁的数据和程序段放入片内Memory,开启cache。     如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank     (8)开启仿真软件的编译优化选项     在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。     以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了  |