现代 CPU 使用流水线(pipelining)以及硬件多线程、乱序执行和指令级并行等技术来尽可能有效地利用资源。尽管如此,某些程序包含的代码和算法还是会破坏流水线的完美执行。例如,我们在程序中常见的链表类型,获取下一个表项中的内容时,会导致间接寻址,从而破坏了硬件预取的效果。这种情况下,当前的流水线将会被清空,而且只会进行取指操作,不会有其他的指令会被执行。使用链表可能是程序的最佳解决方案,但不一定是最有效率的方法。在软件层面还有许许多多的对底层CPU流水产生影响的例子。自顶向下的微架构分析方法旨在当你需要选择算法或数据结构时,提供一些的理论参考依据。
CPU流水线架构
Intel将流水线中的处理分为前端(front-end)和后端(back-end)两部分
前端(front-end)
前端的主要部件如下:
指令获取单元(IFU)每个周期可以从I-cache中提取16字节的指令并推送至指令长度解码组件(ILD),解码后将指令保存到指令队列(IQ)当中。
指令解码器(Instr Decoder)每周期可以从IQ中获取4个指令。指令解码器有3个简单指令解码单元,每个单元每周期可以解码1个简单指令。还有一个复杂指令解码单元,每个周期可以解码一个简单指令或者复杂指令。每条指令可以解码为1个或数个微操作(uops),并存储到指令解码队列(IDQ)当中。如果是由超过4个微操作构成的复杂指令,则是从MSROM中获取的,而不是从I-Cache中。
前端的基本组成部件及功能总结如下:
组件 |
功能 |
性能挑战 |
分支预测单元 (Branch Prediction Unit) |
* 通过预测各种分支类型:条件(conditional)、间接(indirect)、直接(direct)、调用(call)和返回(return),帮助指令预取单元获取最有可能执行的指令。每种类型由特定的硬件来完成。 |
* 减少代码分支或者分支代码的总量,来提高推测执行单元的效率。 |
指令提取单元 (Instruction Fetch Unit) |
* 预取最有可能执行的指令 * 缓存频繁使用的指令 * 预解码和缓冲指令,维持固定带宽的指令流。 |
* |