[CSAPP]提升代码的效率

当我们想要写出效率极高的代码的时候, 我们一般要做到下面两个方面:

  • 有效的算法和数据结构
  • 理解编译器的性能和局限性
  • 编译器的作用和局限性

    虽然一般的编译器都可以在某些方面提高代码的质量, 但是他们对代码的优化总是遵从下面的几点:

  • 不能改变程序的行为
  • 对程序的行为和所处的编译环境所知甚少
  • 快速编译程序的需求
    观察下面的代码:
  • void twiddle1(int* xp, int* yp)
    {
            *xp += *yp;
            *xp += *yp;
    }
    void twiddle2(int* xp, int* yp)
    {
            *xp +=  2\* *yp;
    }
    

    咋一看, 我们觉得这两个程序有着相同的行为, 但是仔细观察之后我们会发现, 在xp和yp不重合的情况下, 第二个函数的效率要比第一个函数的效率要高(只是执行一次取地址和运算的操作), 而在xp和yp重合的情况下, 这两个函数将会产生完全不同的两种结果。
    在此, 我们知道下面的因素会导致代码的效率下降:

  • 两个地址相互交叉
  • 两个进程(函数)共享公共资源
  • 衡量代码效率的因素

    现代处理器速度的衡量因素是由其主频的频率决定的。现在认为, 计算机CPU的频率已经达到了硅半导体的极限值(4GHz). 在计算机科学当中, 用以衡量代码效率的量就是CPE, 表示的是执行一次元操作所需要的时钟次数。

    理解处理机的结构

    一个处理机的模型如下所示:
    [CSAPP]提升代码的效率_第1张图片
    这个处理机主要有几个部分组成:

  • 指令控制单元: 控制执行指令
  • 执行单元: 负责执行相应的指令
  • 指令缓存: 储存最近要执行的指令, 当存在转移指令的时候, 处理机会预测这个操作是否会发生, 甚至会直接执行这条指令, 当确认这条指令会执行的时候, 将操作数写入寄存器或内存, 否则执行相应的分支语句。
  • 同时, 处理机存在一个模块来跟踪处于执行或者等待状态的指令, 并且缓存他们的结果。如果他们被确认将要执行, 则将他们的结果写入相应的内存和寄存器, 如果不, 则处理他们的结果。
  • Load模块, 负责向内存中取数据
  • Store模块, 负责向内存中存入数据
  • 各种程序执行单元, 负责执行原子指令
  • 一些提高代码效率的建议

    通过上面的分析, 我们可以发现:
    其实计算机中的操作甚至并不像我们所看到的汇编中所显示的操作。他包括取指令, 进行逻辑运算, 存取内存等等操作, 操作之间还有空隙的时间来保证每个原子操作的正确性。所以:

  • 尽量使用代价较小的原子操作
  • 尽量减少循环的次数
  • 尽量减少循环的次数, 提高单次循环的效率。
  • 你可能感兴趣的:(CSAPP,笔记)