您的位置:首页 > 编程语言

在即将离开工作了四年的软件业前[zt,一位前辈关于代码优化的总结]

2005-08-17 20:11 519 查看
转自 LinuxFans 论坛,作者 wsm
即将离职 成功的话 将来再也不会做纯软件的东西了 闲来无事写点东西 为了不重复 好像只能写这些个了
代码优化问题:
1.书写代码的时候要仔细考虑数据类型的大小
避免假设int和long具有相同的长度,因为编译器会扩展long字段
定点乘法使用short作为乘法输入,因为现在只有实现的16*16的乘法器
使用浮点运算的时候,必须考虑cpu是否支持浮点,加入编译开关
2.编译代码的依赖性
帮助编译器确定代码的独立性
如代码:
void sum(short *sum, short *in1, short *in2, int N)
{
int i;
for(i=1;i<N;i++)
sum[i] = in1[i]+in2[i]
}
在sum和in1,in2之间存在不确定的依赖性。编译器将要求流水线的下一次读取在sum的本次写入之后再开始。
如果改成:void sum(short *sum, const short *in1, const short *in2, int N)
则编译器可以确认,下一次的取数据可以在计算周期中开始。
3.使用编译器的内部函数实现某些处理
除了加减以外事实上现代的处理器多少都有一些独特的计算支持,比如说两个16比特加减和提取绝对值。注意你在使用的处理器,使用好这些内部定义的额外指令,如双16比特加减很明显可以让你减少一半的处理时间。
4.注意内存访问周期
在一个循环的读取中往往需要注意。这个问题有多个方面:一是你使用的处理器是否支持dma这样的方式。二是你使用的处理器数据带宽如何,对32位带宽的处理器使用俩个周期去分别读取16位的数据就很不明智了。三是你的处理器在一个周期内访问内存几次,对于那种单周期多次访问的处理器,不妨修改你的循环计数方式,充分让处理器在周期内访问存储器。
5.平行的代码
特别针对多处理单元和带时延的处理
多个单元可以同时进行加减和取数。一个时延的取数操作可以和其他单元的数个加减同时执行。
特别例子,一个循环的取数+计算的代码,取数的同时可以在并行单元进行上一次的计算和跳转。
6.软件流水线
同样基于多处理单元
第一步绘制迭代间隔表,其竖行是可使用的处理单元,横行是处理器周期,内容是各指令。当前的横行长度表现了当前的迭带时间。确定最小的迭带时间,一般来说处理单元的使用,指令依赖性和指令的时延决定了可能的最小迭带时间。确定完毕后,保持原有的处理指令,将原有指令向右平移一格,表示软件流水线中开始提前处理的下一个周期的内容。继续这样做,直到表格的最后一个周期的处理单元被充分使用。书写代码的时候,前面的所有周期单独写出,最后一个周期作为循环体。
如果需要排除循环末端的无效指令只要在绘制表格的时候扩展一倍,然后将第二个迭带周期内显示的处理在循环之外单独写出。注意循环周期数的正确计算。
7.使用原始代码环减少软件流水线的代码量
基本思路:那些单独书写的处理和完整的循环体处理的差异可以用一些预先初始化寄存器来掩盖:0+0=0 && 0-0=0
注意循环周期数的正确计算。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: