13. PPro,PII 和 PIII 流水线综述
PPro,PII 和 PIII 微处理器的制造工艺在 Intel 的各种指南手册中有很好的解释和插图。为了理解这些处理器是怎么工作的,推荐你学习这些材料。在此,我只对代码优化相关部分作简要描述。
指令代码从指令cache的16字节对齐的块中取到一个两倍大的缓存中,该缓存能够容纳两个16字节的块。从该缓存传递到解码器的指令块我称之为ifetch块(指令携带块)。ifetch块一般是16字节,但没有对齐。两倍缓存的目的就是希望能够对跨越16字节边界的指令也能解码(16字节边界是指能够被16整除的地址)。
指令长度解码器决定了每个指令的开始和结束位置,和紧接的下一条指令,ifetch块就是根据指令长度解码的结果来定位的。
有三个解码器,因此你可以在一个时钟周期内解码三条指令。 在同一个时钟周期内解码的指令(最多三条)被称为一个解码组。
解码器将指令翻译为微操作、小型的微指令。简单的指令只产生一条微码,复杂的指令可能产生几条微码。 比如ADD
EAX,[MEM]指令解码为两条微码:一条读内存操作数,一条做加法。 把指令分解为微码的目的是使以后的系统处理更为有效。
三个解码器被称为D0,D1和D2。D0能够处理所有的指令。D1和D2只能处理那些只产生一条微码的简单指令。
从解码器出来的微码经过一个短的队列到达寄存器分配表(RAT)。
微码的执行在临时寄存器中进行,以后再写回到永久寄存器诸如EAX,EBX等等。 RAT的目的是给微码分配临时寄存器,并且使寄存器重命名成为可能(见后续章节)
在RAT之后,微码进入了乱序缓存(reorder buffer,ROB)。 ROB的作用是乱序执行。 在微码需要的操作数不可用之前,它将呆在保留站。
当因为前面的微码产生的结果(作为后面某条微码的操作数)还没完成时,ROB在需要该操作数的微码等待期间,会找另一条后面的微码来执行(前提是逻辑正确),从而节省了时间。
就绪态的微码被送入执行单元。执行单元有五个端口:端口0和1能处理算术运算,跳转等等;端口2负责所有的内存读;端口3计算将要被写的内存地址;端口4进行内存写。
在ROB中,一条被执行过的指令被标记为将要引退。 然后它进入引退站。
在这里,微码用过的临时寄存器的内容要写回永久寄存器。 虽然微码能够被乱序执行,但必须有序引退。
后续章节中,我会详细地描述流水线中每一步的吞吐量如何进行优化。