【大话处理器】编写高效代码

一、软件效率

         在软件开发中,就叫软件性能剖析。性能剖析工具分析每个函数(有的工具能分析到每个循环)的执行时间。常用的性能剖析软件有:IBM的Rational Quantify、Intel的VTune、AMD的CodeAnalyst,DSP的软件集成开发环境中也自带有这种工具。

二、减少指令数

1.      使用更快的算法:算法,程序设计的灵魂;(高斯的故事)

2.      选用合适的指令:合适的人做合适的事;(主要是处理器的专用汇编指令)

3.      降低数据精度:比特也要省着用;(单精度浮点数绝对值函数fabsf()比双精度fabs()快)

4.      减少函数调用:不要老打断我;

           a)      将小函数直接写成语句;

           b)      将小函数写成宏;

           c)       将函数声明为内联函数;

5.      空间交换时间:将中间结果保存;(Fibonacci数列某项值的计算、Google百度搜索引擎算法)

6.      减少过保护:避免冗余功能;(函数入参检查、保护可适当去掉)

三、减少处理器不擅长的操作

1.      少用乘法;(可转化为移位运算)

2.      少用除法、求余;

3.      在精度允许的条件下,将浮点数定点化;

4.      尽量减少分支;(if和switch跳转语句会打乱流水线执行,影响效率)

5.      将最有可能进入的分支放在if中,而不是else中;

四、优化内存访问

1.      少使用数组,少使用指针;(用局部变量代替)

2.      少使用全局变量;(用局部变量代替)

3.      一次多访问一些数据;

4.      数据对齐访问:对于n字节的变量,它的起始地址应该为n的整数倍;

5.      大数据结构时的Cacheline对齐;(Intel处理器的Cache line大多为64 byte,在对大数据结构分配内存时,起始地址最好为64 byte的整数倍,这样Cachemiss的次数最少。)

6.      程序、数据访问符合Cache的时间、空间局部性;(两重for循环处理二维数组例子;程序组织、存储符合Cache局部性原则)

7.      多线程编程时,避免falsesharing;

8.      自己管理内存的动态分配;(频繁的动态分配和释放内存所带来的危害)

9.      隐藏数据搬移时间;(根据处理器支持,用DMA将SRAM中数据搬移到处理器、Cache预取机制)

五、充分利用编译期进行优化

1.      编译器的结构;(编译原理与编译器构造)      

2.      编译器提供了几级优化选项:选择优化级别;(根据具体情况适度优化)

3.      编译器会计算常量;

4.      简化表达式;(消除重复计算)

5.      提取公共代码;(把两个分支中的公共代码提到外面)

6.      循环展开、软件流水;(比如可以使用编译期的预编译指令)

7.      自动向量化;(使用关键字restrict)

8.      高效的数据组织;(编译器对变量、函数分配存储空间,减少Cache miss)

9.      指令并行化;

10.   编译器更懂处理器;

六、 利用多核来加速程序

1.      并行计算;(分工:任务划分、数据划分、数据流划分;Amdahl’s law,阿姆达尔定律:串行与并行分开;多线程编程)

2.      OpenMP;(并行编程框架,适合共享内存系统、多核处理器)

posted @ 2011-11-23 15:21  斯涵  阅读(489)  评论(0编辑  收藏  举报