读完《深入理解计算机系统》,我们的编程不只是简简单单的码代码。而是要结合系统的基础去写更优化的代码。我们用理解计算机的工作方式去写代码。用更低层次的目光去审视我们的代码,也许一个简单的循环就能改变代码的整体效率。
现代的编译器很复杂,其为程序作了很多工作,目标都是让程序更安全更快。比如我们的编译优化选项-Og -O1 -O2 -O3等,但是也由于优化,我们的机器指令被安排得“面目全非”,不信大家可以使用优化后的代码进行反汇编看看,会大大超出你的想象。
以下有几条准则可以适用
1.消除循环的低效率,绝不做增加额外的计算,该挪动到循坏外的就挪到循坏外
2.减少过程调用,当然这个是个双刃剑,比如内联函数的使用,但是如果减少的太多,又会让我们的代码逻辑乱七八糟
3.减少不必要的内存引用,这里最好的例子就是拷贝构造函数和移动构造函数。毕竟访存和cpu的执行周期比起来,速度慢得太多。
4.尽量提高cache命中率,这个就要求写代码的时候,频繁访问的数据尽量放到一条cacheline里,或者做cacheline的对齐,这里又是一把双刃剑,做对齐后有可能会浪费不少空间,毕竟cache还是比较宝贵的。
5.循环展开,使用循环分块,减少循环的迭代次数,增加每次迭代计算的元素数量。减少了不直接有助于程序结果的操作的数量,提供一些方法可以优化代码,减少整个计算中关键路径上的操作数量。
6.提高并行性,当代计算机体系基本都是多核架构,不同的核可以处理不同的数据,当然这里数据的拆分很重要,特别是数据的相关性对并行影响很大。
7.书写适合用条件传送实现的代码,毕竟分支预测是miss的代价是比较高的,需要重新填写流水线。
8.理解内存的性能,内存总线带宽,能是用寄存器变量就不使用内存变量。
9.通过使用多个积累变量和重新结合等技术,找到方法提高指令集的并行。
10.尽量减少cache line的miss和cache的抖动。
11.把高级语言的代码反汇编,从汇编中找到优化的方式。