上一讲,我给你初步介绍了CPU的流水线技术。乍看起来,流水线技术是一个提高性能的灵丹妙药。它经过把一条指令的操做切分红更细的多个步骤,能够避免CPU“浪费”。
每个细分的流水线步骤都很简单,因此咱们的单个时钟周期的时间就能够设得更短。这也变相地让CPU的主频提高得很快。java
这一系列的优势,也引出了现代桌面CPU的最后一场大战,也就是Intel的Pentium 4和AMD的Athlon之间的竞争。在技术上,这场大战Intel能够说输得很是完全,Pentium 4系列以及
后续Pentium D系列所使用的NetBurst架构被彻底抛弃,退出了历史舞台。可是在商业层面,Intel却经过远超过AMD的财力、本来就更大的市场份额、无所不用的竞争手段,以及最终
壮士断腕般放弃整个NetBurst架构,最终依靠新的酷睿品牌打败了AMD。服务器
在此以后,整个CPU领域竞争的焦点,再也不是Intel和AMD之间的桌面CPU之战。在ARM架构经过智能手机的快速普及,后来居上,超越Intel以后,移动时代的CPU之战,
变成了高通、华为麒麟和三星之间的“三国演义”。架构
咱们在第3讲里讲过,咱们其实并不能简单地经过CPU的主频,就来衡量CPU乃至计算机整机的性能。由于不一样的CPU实际的体系架构和实现都不同。一样的CPU主频,
实际的性能可能差异很大。因此,在工业界,更好的衡量方式一般是,用SPEC这样的跑分程序,从多个不一样的实际应用场景,来衡量计算机的性能。性能
可是,跑分对于消费者来讲仍是太复杂了。在Pentium 4的CPU面世以前,绝大部分消费者并非根据跑分结果来判断CPU的性能的。你们判断一个CPU的性能,
一般只看CPU的主频。而CPU的厂商们也经过不停地提高主频,把主频当成技术竞赛的核心指标。spa
Intel一贯在“主频战争”中保持领先,可是到了世纪之交的1999年到2000年,状况发生了变化。1999年,AMD发布了基于K7架构的Athlon处理器,其综合性能超越了当年的Pentium III。
2000年,在大部分CPU还在500~850MHz的频率下运行的时候,AMD推出了第一代Athlon 1000处理器,成为第一款1GHz主频的消费级CPU。在2000年先后,AMD的CPU不但性能和主频比Intel的要强,价格还每每只有Intel的2/3。设计
在巨大的外部压力之下,Intel在2001年推出了新一代的NetBurst架构CPU,也就是Pentium 4和PentiumD。Pentium 4的CPU有个最大的特色,就是高主频。
2000年的Athlon 1000的主频在当时是最高的,1GHz,然而Pentium 4设计的目标最高主频是10GHz。3d
为了达到这个10GHz,Intel的工程师作出了一个重大的错误决策,就是在NetBurst架构上,使用超长的流水线。这个超长流水线有多长呢?咱们拿在Pentium 4以前和以后的CPU的数字作个比较,
你就知道了。blog
Pentium 4以前的Pentium III CPU,流水线的深度是11级,也就是一条指令最多会拆分红11个更小的步骤来操做,而CPU同时也最多会执行11条指令的不一样Stage。
随着技术发展到今天,你平常用的手机ARM的CPU或者Intel i7服务器的CPU,流水线的深度是14级。生命周期
能够看到,差很少20年过去了,经过技术进步,现代CPU仍是增长了一些流水线深度的。那2000年发布的Pentium 4的流水线深度是多少呢?答案是20级,比Pentium III差很少多了一倍,
而到了代号为Prescott的90纳米工艺处理器Pentium 4,Intel更是把流水线深度增长到了31级。ip
要知道,增长流水线深度,在同主频下,实际上是下降了CPU的性能。由于一个Pipeline Stage,就须要一个时钟周期。那么咱们把任务拆分红31个阶段,
就须要31个时钟周期才能完成一个任务;而把任务拆分红11个阶段,就只须要11个时钟周期就能完成任务。在这种状况下,31个Stage的3GHz主频的CPU,其实和11个
Stage的1GHz主频的CPU,性能是差很少的。事实上,由于每一个Stage都须要有对应的Pipeline寄存器的开销,这个时候,更深的流水线性能可能还会更差一些。
我在上一讲也说过,流水线技术并不能缩短单条指令的 响应时间这个性能指标,可是能够增长在运行不少条指令时候的 吞吐率。由于不一样的指令,实际执行须要的时间是不一样的。
咱们能够看这样一个例子。咱们顺序执行这样三条指令。
1. 一条整数的加法,须要200ps。
2. 一条整数的乘法,须要300ps。
3. 一条浮点数的乘法,须要600ps。
若是咱们是在单指令周期的CPU上运行,最复杂的指令是一条浮点数乘法,那就须要600ps。那这三条指令,都须要600ps。三条指令的执行时间,就须要1800ps。
若是咱们采用的是6级流水线CPU,每个Pipeline的Stage都只须要100ps。那么,在这三个指令的执行过程当中,在指令1的第一个100ps的Stage结束以后,第二条指令就开始执行了。
在第二条指令的第一个100ps的Stage结束以后,第三条指令就开始执行了。这种状况下,这三条指令顺序执行所须要的总时间,就是800ps。那么在1800ps内,使用流水线的CPU比单指令周期的CPU就能够多执行一倍以上的指令数。虽然每一条指令从开始到结束拿到结果的时间并无变化,也就是响应时间没有变化。可是一样时间内,完成的指令数增多了,也就是吞吐率上升了。
那到这里可能你就要问了,这样看起来不是很好么?Intel的CPU支持的指令集很大,咱们以前说过有2000多条指令。有些指令很简单,执行也很快,好比无条件跳转指令,
不须要经过ALU进行任何计算,只要更新一下PC寄存器里面的内容就行了。而有些指令很复杂,好比浮点数的运算,须要进行指数位比较、对齐,而后对有效位进行移位,而后再进行计算。
二者的执行时间相差二三十倍也很正常。既然这样,Pentium 4的超长流水线看起来很合理呀,为何Pentium 4最终成为Intel在技术架构层面的大失败呢?
第一个,天然是咱们在第3讲里讲过的功耗问题。提高流水线深度,必需要和提高CPU主频同时进行。由于在单个Pipeline Stage可以执行的功能变简单了,也就意味着单个时钟周期内可以完成的事情变少了。因此,只有提高时钟周期,CPU在指令的响应时间这个指标上才能保持和原来相同的性能。
同时,因为流水线深度的增长,咱们须要的电路数量变多了,也就是咱们所使用的晶体管也就变多了。主频的提高和晶体管数量的增长都使得咱们CPU的功耗变大了。
这个问题致使了Pentium 4在整个生命周期里,都成为了耗电和散热的大户。而Pentium 4是在2000~2004年做为Intel的主打CPU出如今市场上的。这个时间段,正是笔记本电脑市场快速发展的时间。在笔记本电脑上,功耗和散热比起台式机是一个更严重的问题了。即便性能更好,别人的笔记本能够用上2小时,你的只能用30分钟,那谁也不爱买啊!
更况且,Pentium 4的性能还更差一些。 这个就要咱们说到第二点了,就是上面说的流水线技术带来的性能提高,是一个理想状况。在实际的程序执行中,并不必定可以作获得。
还回到咱们刚才举的三条指令的例子。若是这三条指令,是下面这样的三条代码,会发生什么状况呢?
int a = 10 + 5; // 指令 1 int b = a * 2; // 指令 2 float c = b * 1.0f; // 指令 3
咱们会发现,指令2,不能在指令1的第一个Stage执行完成以后进行。由于指令2,依赖指令1的计算结果。一样的,指令3也要依赖指令2的计算结果。这样,即便咱们采用了流水线技术,
这三条指令执行完成的时间,也是 200 + 300 + 600 = 1100 ps,而不是以前说的 800ps。而若是指令1和2都是浮点数运算,须要600ps。那这个依赖关系会致使咱们须要的时间变成1800ps,
和单指令周期CPU所要花费的时间是同样的。这个依赖问题,就是咱们在计算机组成里面所说的 冒险(Hazard)问题。这里咱们只列举了在数据层面的依赖,也就是数据冒险。在实际应用中,还会有 结构冒险、控制冒险等其余的依赖问题。
对应这些冒险问题,咱们也有在 乱序执行、 分支预测等相应的解决方案。咱们在后面的几讲里面,会详细讲解对应的知识。
可是,咱们的流水线越长,这个冒险的问题就越难一解决。这是由于,同一时间同时在运行的指令太多了。若是咱们只有3级流水线,咱们能够把后面没有依赖关系的指令放到前面来执行。
这个就是咱们所说的乱序执行的技术。比方说,咱们能够扩展一下上面的3行代码,再加上几行代码。
int a = 10 + 5; // 指令 1 int b = a * 2; // 指令 2 float c = b * 1.0f; // 指令 3 int x = 10 + 5; // 指令 4 int y = a * 2; // 指令 5 float z = b * 1.0f; // 指令 6 int o = 10 + 5; // 指令 7 int p = a * 2; // 指令 8 float q = b * 1.0f; // 指令 9
咱们能够不先执行一、二、3这三条指令,而是在流水线里,先执行一、四、7三条指令。这三条指令之间是没有依赖关系的。而后再执行二、五、8以及三、六、9。这样,
咱们又可以充分利用CPU的计算能力了。可是,若是咱们有20级流水线,意味着咱们要确保这20条指令之间没有依赖关系。这个挑战一会儿就变大了不少。毕竟咱们平时撰写程序,
一般先后的代码都是有必定的依赖关系的,几十条没有依赖关系的指令可很差找。这也是为何,超长流水线的执行效率发而下降了的一个重要缘由。
相信到这里,你对CPU的流水线技术,有了一个更加深刻的了解。你会发现,流水线技术和其余技术同样,都讲究一个“折衷”(Trade-Off)。一个合理的流水线深度,
会提高咱们CPU执行计算机指令的吞吐率。咱们通常用IPC(Instruction Per Cycle)来衡量CPU执行指令的效率。
IPC呢,其实就是咱们以前在第3讲讲的CPI(Cycle Per Instruction)的倒数。也就是说, IPC = 3对应着CPI= 0.33。Pentium 4和Pentium D的IPC都远低于本身上一代的Pentium III以及竞争对手AMD的Athlon CPU。过深的流水线,不只不能提高计算机指令的吞吐率,更会加大计算的功耗和散热问题。Intel本身在笔记本电脑市场,也很快放弃了Pentium 4,而是主推了使用Pentium III架构的图拉丁CPU。
而流水线带来的吞吐率提高,只是一个理想状况下的理论值。在实践的应用过程当中,还须要解决指令之间的依赖问题。这个使得咱们的流水线,特别是超长的流水线的执行效率变得很低。要想解决好 冒险的依赖关系问题,咱们须要引入乱序执行、分支预测等技术,这也是我在后面几讲里面要详细讲解的内容。