氮气
——中央处理器加速技术解密
2018-12-21蒲青文西昌学院
蒲青文 西昌学院
氮气,作为超级跑车在赛道上扭转乾坤的利器,可以将引擎的最后一点潜能完全压榨出来,以此获得爆裂般的加速。而CPU作为对速度有更高要求的计算机核心部件,对于速度的追求自然是用户以及工程师们的终极梦想,因此各个实验室的工程师们也必将为此绞尽脑汁……
我们就以Intel CPU的发展为例为简要阐述一下CPU中的“氮气”加速技术是怎么一点点被开发出来的。
1 原始级,蛮荒状态-1987年
Intel在1978-06-08创造了8086处理器,这时处理器的执行流程非常简单,就是从内存中读取操作码后将操作码译码解析成微指令,并由微指令驱动逻辑电路去完成具体计算操作,然后再读取下一条指令。
以上操作可被概括为取指令、译码和执行这三步,而且每次都要等到这三个步骤都完成后才能执行下一条指令。
2 上古级,指令缓存-1982年
由于CPU的执行速度远高于内存的读取速度,因此Intel发现整个CPU的性能瓶颈出现在内存读取这一环节上。而又因为绝大多数指令编译的操作码仅几个字节大小,所以Intel在1982年发布了一款新CPU 80186,并且增加了指令缓存机制。
80186拥有一个6字节的指令缓存器,在每次剩余空间大于等于3字节时,80186就会自动提前将下一条指令从内存中读取进来,进而大大降低了操作码的读取延迟。
3 古代级,数据缓存-1985年
由于指令缓存机制在80186上取得了巨大成功,因此Intel在1985年发布的80386上面将指令缓存提高到了最大8KB,相较80186增加了1300余倍,并增加了数据缓存机制。
4 近代级,多流水线-1989年
由于内存的延迟已经被Intel在80386上尽可能的优化,因此Intel的工程师们这一次将优化的目光锁定在指令执行的流程上,他们首先将指令的执行细分为五个步骤,分别为:
Step1:取指令,将操作码从指令缓存中取出;
Step2:译码,将操作吗翻译为具体的微指令;
Step3:转址,将内存地址和偏移进行转换;
Step4:执行,指令在该阶段真正执行运算(由微指令控制硬件逻辑电路去完成);
Step5:退出,将执行结果写回到寄存器或者内存。
一个指令必须要经过这5步才能执行完成,而CPU执行这5步所需要占用的CPU时间就被称之为这条指令执行所需的时钟周期,需要时钟周期越短的指令,其在一秒钟内可以执行的次数就越多,效率就越高。
Intel在1989年第一次将五级流水线技术应用到了80486处理器中,使得新处理器在频率仅为上代一倍多的情况下获得了数倍于上代CPU的理论执行速度。
5 现代级,超流水线-1993年
既然流水线这么强悍,那么为什么不多搞一些呢?其实Intel的工程师们也是这么想的,因此Intel在1993年推出的首代奔腾(因为586这个代号被占用,所以启用了新名字Pentium)处理器时,第一次将超标量流水线结构应用到自己的产品中。
新款奔腾处理器的超标量流水线由两条五级流水线构成,但是限于一些底层逻辑限制,第二条流水线能够执行的指令类别有所受限,并且在遇到类似于JMP、CALL等转移指令时会使得第二条流水线失效,但是即便如此,启用超流水线结构的CPU也比其他同等工况下快了近1倍。
6 次代级,乱序执行-1995年
通过流水线的优化让Intel的工程师们尝到了甜头,但是因为程序代码的前后顺序逻辑等问题,在增加过多的流水线对于指令的执行速度不会再有明显的提高,因此Intel的工程师们将优化目标锚定在流水线本身逻辑的修改及加强上。
Intel在1995年推出的奔腾Pro处理器中首次应用了可以极大改进流水线工作效率的乱序执行(Out-of-Order, OOO)技术,并且为了缓解因JMP、JNZ等转移指令对超标量流水线的影响而推出了指令预测(猜测执行/分支预测)技术,这两种技术的出现使得Intel的流水线已经被优化到了极致。除此之外,奔腾Pro更是将原先的五级流水线升级到了12级,这使得奔腾Pro处理器中的每条流水线理论上可同时执行12条指令。
经过如此优化的流水线已经明显不符合当时的主流情况,进而导致奔腾Pro上的流水线在大多数情况下实际是在等待新指令的传入,而正是由于Intel这次跨时代的流水线优化,使其早在23年前便为今天的漏洞埋下了祸根,并且使其养成了挤牙膏的坏习惯,看来车开的太快果然容易出问题。
7 后现代级,超线程-2002年
由于上次乱序执行与指令预测的双剑合璧,使得CPU处理指令的速度飙涨,进而导致指令被执行的速度比处理器能够提供指令的速度更快,因此CPU的超标量流水线部件在大部分时间处于空闲状态。为了让整套流水线部件能够完全发挥其应有的作用,Intel在2002年为奔腾4处理器加入了第二套前端部件(例如寄存器、译码器等),这样对于操作系统来说,它就能看到两个处理器了。这样来自两套前端部件的所有的指令被一个共享的流水线部件执行,进而充分的发挥了其本来作用,而这种技术就被称之为超线程。