● 在软件流水线期间,处理流水线标号。 ● 分配寄存器的用法。 ● 分配功能单元。
TI提供的汇编优化器可以得到很高的效率,一般可以满足性能上的要求。 优化中的问题、
在优化过程中,总是要对程序进行一定的改动,这样经常会出现一些问题。
1) 优化结果的验证、
优化过的程序往往不知道是否运行正确,这就需要加以验证。一般采用的办法就是通过测试序列来验证。测试序列指的是对于不同的算法所取的一组特殊的数据,这些数据可以准确的反映算法的特性。测试序列中每组数据包括输入数据和输出数据,通过对输入数据的运算,把结果与输出数据进行比较,判断程序的正确性。一些常见的算法,一般都提供了测试序列。还有一些,没有测试序列。这时就需要根据算法的特点,自己构造测试序列,进行验证。构造的时候,注意序列最好有几组,数据最好有一定的长度,这样验证的更准确。 2) 内存泄漏的问题、
C64X系列DSP的内部存储空间有1MB,其中程序和数据还有CPU的二级缓存将共享这片空间,因此当程序的运行不正常时,很有可能就是内存泄漏造成的。因此,在程序设计中,应尽量不用指针,同时注意进行边界检测。 程序设计的一些方法
程序设计时,一切以满足实际的要求为目标。在实际的设计中,除了优化能够提高性能以外,还可以采取其他的办法,利用DSP的特性,提高程序的运行性能,满足实际的设计要求。
1) 把程序和经常要用的数据放入片内RAM
片内RAM与CPU
工作在同一时钟频率,比片外RAM性能高得多。因此把程序放在片内可以大大提高运行的速度。同时对于一些经常要用到的数据,放入片内,也会节省处理时间。
2) 通过DMA技术搬移数据
对于C64X芯片,其片内RAM有1MB,但是对于一些大型的图像处理算法而言,仍可能是不够的,因此经常通过DMA技术,把需要用到的数据搬入片内,把不需要的搬到片外,可以大大的提高程序的运行速度。
3) CACHE的使用
增大CACHE,可以明显的提高性能。但是C64X系列DSP中程序和数据还有CACHE共享片内RAM,因此增大CACHE,就减小了实际的片内可用空间,设计中需要注意。
使用特殊数据类型,register类型、volatile类型、const类型等;
优化汇编代码
在实现汇编代码功能后,优化汇编代码的方法包括: 1)并置指令;
2)重写或重组代码以防止流水线保护延迟; 3)获取指令时最小化延迟。
C语言编程优化方法
1利用c内部函数计算各自乘积的和 2减少判断转换 3循环展开 4软件流水线方法
1指针运算代替数组索引
2求余运算,只要求是求 2n 方的余数,均可使用位操作的方法来代替。 3使用增量和减量操作符 4使用复合赋值表达式 5提取公共的子表达式
6结构体成员的布局:按数据类型的长度排序,长的类型放在短的前面(按数据类型的长度排序本地变量) 7把频繁使用的指针型参数拷贝到本地变量:避免在函数中频繁使用指针型参数指向的值 循环优化
1 充分分解小的循环
2 提取公共部分:对于一些不需要循环变量参加运算的任务可以把它们放到循环外面 3 循环计数器应该是递减的。
4 使用 do … while 循环编译后生成的代码的长度短于 while 循环。
5 循环展开:对于中间变量或结果被更改的循环,编译程序往往拒绝展开;循环展开会影响矢量运算优化。 6 Switch语句中根据发生频率来进行case排序 7 将大的switch语句转为嵌套switch语句
8 switch 中每一种情况下都有很多的工作要做,那么把整个 switch 语句用一个 指向函数指针的表 来替换会更加有效
9 选择好的无限循环 :for ( ;; ) 指令少,不占用寄存器,而且没有判断、跳转,比 while (1) 好
提高CPU的并行性
1 使用并行代码:尽可能把长的有依赖的代码链分解成几个可以在流水线执行单元中并行执行的没有依赖的代码链。
2 避免没有必要的读写依赖:在一段很长的又互相依赖的代码链中,避免读写依赖显得尤其重要:如果读写依赖发生在操作数组时,许多编译器不能自动优化代码以避免读写依赖。凡是在循环里对一个结构体的两个以上的元素执行了访问,就有必要建立中间变量了
函数优化 1 Inline函数
2 不定义不使用的返回值 3 减少函数调用参数 4 所有函数都应该有原型定义 5 尽可能使用常量(const)
6 把本地函数声明为静态的(static) 变量优化
1 register变量:声明局部变量的时候可以使用 register关键字。
2 在最内层循环避免使用全局变量和静态变量,除非你能确定它在循环周期中不会动态变化, 3 尽量避免把一个变量地址传递给另一个函数 4 同时声明多个变量优于单独声明变量