博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
程序性能优化
阅读量:4993 次
发布时间:2019-06-12

本文共 1807 字,大约阅读时间需要 6 分钟。

作为一个性能癖,关于程序优化的奥秘怎能错过?

咱们可以将优化分为三个层次:

   1、High-level design:即选择适当的数据结构和算法。

  2、Basic code principles:注意避免两个optimization blockers,使编译器可以顺利优化。还要注意尽量不要使用连续的函数调用和不必要的内存访问。中间值就不要写入内存了,求得最终值再来写入。

  3、Low-level optimizations:unroll loops即通过增加每次循环中处理的元素个数以减少迭代次数;通过multiple accumulators(比如说将奇数项和偶数项分开算)或reassociation(类似结合律)来提高instruction-level parallelism。这需要对存储器的微结构有所了解。除此之外,还可以将conditional jump用conditional move代替。

一些概念:

   这里衡量性能的标准主要是CPE(cycles per element),即增加一个元素需要相应增加的时钟周期,自然是越小越好。 性能的制约主要有两个:latency bound 和throughput bound,前者是指指令必须按严格顺序执行,这样就限制了处理器对instruction-level parallelism的利用;而后者就关乎你处理器的硬实力了,除了投入更多的人民币以外,我们对它也无能为力 =。=

  有了parallelism后,多条pipeline可以同时执行。决定性能的关键在于那一条critical path,即在该路径上每一次的迭代必须等前一次迭代执行完才可继续。若要优化自然要抓住這个主要矛盾! conditional move的好处: 高级语言中类似于if, while, for等语句,对应于汇编中的conditional jump,即jb, jne之类的分支结构。cpu一般会进行branches predictions来发挥其pipeline的作用,而预测都是分支会被执行。一般情况下,比如说 while ( i < n ) 这种,就只有最后一次错误,所以总的来说分支预测能起到不错的优化效果。但是如果使预测正确的可能性不高的情况下,比如说有个数组a[i],它的元素是任意整数,那么判断条件为if ( a[i] > 0 )时,只有一半的几率正确。这样每次misprediction都要将已经并发执行的指令回退,这些penalities累积起来,后果不堪设想。

   解决办法使使用conditional move取代conditional branch。具体如下

优化前代码片段:

void max( int a, int b){   int i;  if ( a > b)   i = a;  else      i = b;}

改成:

void max ( int a, int b){  int i = a > b ? a : b;}

后面这种情况下,处理器会计算出a, b 的值,然后再根据判断条件是否为真来赋给i。虽然要多计算一个值,但是这里的额外开销远小于分支预测错误的额外开销。

write/read dependency:

  书上写the load unit can only initiate one load operation every clock cycle,所以有内存写入的操作一定要等到前一次内存写入完成。在内存写入后接着进行内存读取自然不是明智的选择。应尽量避免内存的读写依赖。将中间值存在临时变量中,最终值才写入内存。

 

Program Profiling:

  如果是一个大的程序,我们需要借助一些工具来进行分析,找出可以优化的部分。GPROF可以分析函数调用,我们就可以针对调用次数多或调用周期长的函数进行优化。在linux下可以使用valgrind来分析。

 

   最后介绍一个有意思的定律叫Amdahl's Law,这里包含一个计算整体优化度的公式。它主要使说如果我们要提高整体的优化度,必须对大部分都进行优化。对小局部即使进行优化度很高的优化,它能给整体带来的性能提升也非常局限。

转载于:https://www.cnblogs.com/justforfun12/p/4951575.html

你可能感兴趣的文章
番茄时间
查看>>
四位计算机的原理及其实现【转】
查看>>
mediawiki简易安装文档
查看>>
Ubuntu server 命令备忘
查看>>
yum常用操作
查看>>
MES系统框架及MES开源框架|C/S框架网软著产品
查看>>
以boost::function和boost:bind取代虚函数
查看>>
linux 下启动SVN服务
查看>>
vue框架学习
查看>>
现代计算机接口实验 (三)8255实验
查看>>
spring——获取ClassLoader
查看>>
javascript函数
查看>>
luogu4093 序列 (cdq分治优化dp)
查看>>
BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
查看>>
从零开始学算法(一)
查看>>
d3d 纹理坐标1:1对应到屏幕坐标.
查看>>
SQL Server优化器特性-隐式谓词
查看>>
国内不谈Java--硅谷有感
查看>>
hdu3371
查看>>
zoj1456 Minimum Transport Cost
查看>>