chap5:优化程序性能

这一章主要讲的是代码级的优化。

 

5.1、优化编译器的能力和局限性

        大多数现代编译器向用户提供了对代码优化的功能,gcc提供了‘O1','O2'和’O3'三项优化控制,Visual studio的优化控制可以在:项目-->properties-->configuration-->c/c++-->optimization中设置优化控制。

        但编译器受到妨碍优化的因素(optimization blocker)的阻碍。妨碍优化的因素举例:

1、存储器别名的使用(memory aliasing):如果编译器不能确定两个指针是否指向同一个位置,就必须假设任何情况都有可能,限制了可能的优化策略。eg:

 

因为f1的引用次数比f2的引用次数多一倍,所以编译器会尝试优化f1,使其达到f2的效果,但如果xp==yp,f1和f2并不等价,从而f1并为得到优化。

2、函数调用:大多数编译器不会试图判断一个函数是否有副作用,编译器会保持所有的函数调用不变。eg:

由于f()改变了counter的值,所以f1和f2并不等价。由于这个原因,,编译器会保持所有的函数调用不变。

包含函数的代码可以通过”内联“函数来优化。

 

5.2、表示程序性能

        程序性能度量标准:每元素的周期数(cycles per element,CPE),通常通过最小二乘方拟合(least squares fit)来得到CPE的有效值。

 

5.3、程序实例:向量里元素的合并

 

5.4、消除循环的低效率

每次循环迭代时都必须对测试条件求值,向量的长度并不会随循环的进行而改变,所以把vec_length(v)移到循环外,优化后:

 

编译器会保持函数调用的存在,所以此处编译器不会优化。

5.5、减少过程的调用

过程调用会带来相当大的开销,而且会妨碍编译器对大多数形式的程序优化。所以把get_vec_start(v)移到循环外,优化后

 

5.6、消除不必要的存储器引用

CPU从寄存器里读写比从存储器里读写快约100倍。(不考虑cache)

在第i次迭代中,程序读出这个位置处的值,乘以data[i],再将结果存回到dest,每次迭代开始时从dest读出的值就是上次迭代最后写入的值,可以引入一个临时变量acc来消除这样无用的存储i读写。优化后:

 

5.8、循环展开

循环展开能够从两方面提供程序的性能,一是它减少了不直接有助于程序结果的操作的数量,例如循环索引计算和条件分支(或条件判断);二是它提供一些方法可以进一步优化代码,减少整个计算中关键路径上的操作数量。

思想:循环展开k次,则循环上限为n-k+1;  利用k=2优化后

 

5.9、提高并行性

在每次计算acc时,不能计算acc的新值。虽然硬件功能单元能够每个时钟周期开始一个新的操作,但是它只会每L个周期开始一条新操作,这里L是合并操作的延迟。注意:IA32指令集只有很少量的寄存器来存放累积的值,如果我们的并行度p超过了可用的寄存器数量,那么编译器会把某些临时值存放到栈中。现在体会到x86-64增加的八个寄存器的价值了。(P359-P360)

利用p=2个累积变量对combine优化:

 

 

分析优化结果:下图是每一步优化后combine函数的CPE值(在表格中,下一次优化基于上一次,F*表示float,D*表示double)

 

5.13、总结/应用

本章描述了许多优化程序性能的基本策略:

1、高级设计:选择合适的算法和数据结构;

2、基本编码原则:

     消除连续的函数调用。如果可能将计算移到循环外;

     消除不必要的存储器引用。引入临时变量来保存中间结果。只有在最后的值计算出来时,才将结果存放到数组或全局变量中。

3、低级优化

     展开循环,降低开销,并且使得进一步优化成为可能(并行);

     通过使用例如多个累积变量和重新结合等技术,找到方法提高指令级并行;

     用功能的风格重写条件操作,使得编译采用条件数据传送(没仔细看);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值