现在的CPU处理器一般都是超流水线工作,动不动就是10级以上流水线,超高主频,这两者之间有什么关系呢?今天就跟大家科普下CPU流水线的工作原理,以及他们之间的关系。
说到流水线,很多人会想到富士康;说到富士康,很多人会想到张全蛋。作为富士康 3 号流水线资深质检员,下面就请张全蛋给大家科普下什么是流水线,大家鼓掌欢迎。
Micheal Jack 眼中的流水线
大家好,我是张全蛋,英文名叫Micheal Jack,法文名叫霍雷呆-杰Q赖,大家也可以叫我查理。作为iPhone 手机 3 号流水线的资深质检员,我很忙的,每分钟都是几百万的生意。像我们富士康这样的transnational enterprise,经常会和不同国家的客户说一些技术上的meeting啊、下班陪他们message啊,都需要英文的。像我们厂里不会说英语的啊,都会被经理 fire 掉的。在我们厂里,流水线叫法太 low了,我们都叫 pipeline,一条pipeline,每个人分工不同,从手机原材料到成品iPhone ,只需要短短几分钟。嵌入式C语言自我修养
查理很忙,介绍到这里就走了,接下来我们继续了解下什么叫流水线。
流水线是工业大生产下的产物。在农业社会做一部手机,需要的是工匠、手艺人,就像故宫里制作钟表的那些匠人一样,是需要拜师学艺、慢慢学习的:从手机组装、质检、贴膜、包装都是一个人,什么都要学。手艺人慢工出细活,但成本很高,到了工业化社会就不一样了:大家分工合作,将做手机这个复杂过程拆分为多个简单步骤,每个人负责一个步骤,经过刻意(机械)练习和培训,就可以很快上手。每个人都做自己最擅长的,可以大大提高工作效率。
如果每个人都单独做一部手机,焊接电路、组装成品这一步骤一般人需要8分钟,测试检验一般需要4分钟,贴膜包装成盒一般需要4分钟,总共需要16分钟。每16分钟,如果有3个工人的话,一共可以生产3部手机。一个新员工从进厂开始,要培训学习三个月才能掌握所有的技能,才能上岗。如果引入生产流水线就不一样了,每个人只负责一个工序,比如赵铁柱只负责焊接电路、组装手机,李小花只负责贴膜,进厂培训3天就可以快速上手了,对工人的技能要求大大降低!而且随着时间积累,每个人对自己所负责的工序越来越熟练,每道工序需要的时间大大减少:赵铁柱焊接电路越来越顺手,花费时间从原来的8分钟缩减为4分钟;张全蛋的质量检验练得如火纯情,整个流程做完只需要2分钟;李小花的贴膜技术也越来越溜了,从贴膜到包装2分钟搞定。每16分钟,赵铁柱可以焊接4块电路板 ,整个流水线可以生产出4部手机,产能整整提升了33.33%!老板高兴,赵铁柱高兴,张全蛋和李小花更高兴,因为每做2分钟,他们还可以休息2分钟,刷刷微博滑个抖音,岂不乐哉!
看到这里可能有人抬杠了:你这么算是不对的,每道工序所用的时间都变为原来的一半,怎么可能做得到?其实要做到不难的,只要工序拆解得合理,容易上手,再加上足够时间的机械重复,很多人都可以做得到。只要奖金发到位,蛋糕店里的小姐姐夹蛋糕的速度比你眨眼的速度都快,银行柜台的小李数钞票的速度比点钞机都快,买单时饭店前台的小妹摁计算器的速度比你掏钱的速度都快。
一条指令的执行一般要经过:取指令、翻译指令、执行指令三个基本流程。CPU内部的电路分为不同的单元:取指单元、译码单元、执行单元等,指令的执行也是按照流水线工序一步一步执行的。我们假设每一个步骤执行时间都是一个时钟周期,那么一条指令执行需要3个时钟周期。
CPU 执行指令的3个时钟周期里,取指单元只在第一个时钟周期里工作,其余两个时钟周期都处于空闲状态,其它两个执行单元也是如此,效率太低了,消费者无法接受,老板也不能接受。解决方法就是引入流水线,让流水线每一颗螺丝钉都马不停蹄地运转起来,最好一刻也不要停。
引入流水线工作模式后可以看到,除了刚开始第一个时钟周期大家还可以偷懒外,其余的时间都不能闲着:从第二个时钟周期开始,当译码单元在翻译指令1时,取指单元也不能闲着,要接着去取指令2。同样如此,从第三个时钟周期开始,当执行单元执行指令1时,译码单元也不能闲着,要接着去翻译指令2,而取指单元要去取指令3。从第四个时钟周期开始,每个电路单元都会进入满荷负载工作状态,像富士康工厂里的流水线一样,源源不断地执行一条条指令。
引入流水线后,虽然每一条指令执行流程不变,还是需要3个时钟周期,但是从整条流水线的输出看来,差不多平均每个时钟周期就能执行一条指令。原来执行一条指令需要3个时钟周期,现在平均只需要1个时钟周期,CPU 性能提升了不少。
流水线的本质其实就是拿空间资源换时间。将每条指令分解为多步,指令的每一步都有独立的电路来执行,并让不同指令的各步操作重叠,从而实现几条指令并行处理,从而加快程序的运行。
CPU内部的流水线如此,富士康工厂里的iPhone流水线也是如此,通过不断往流水线增加人手来提高流水线的生产效率,也就是吞吐率。
想知道什么是超流水线,让我们再回到富士康。
在富士康 3 号 iPhone 流水生产线上,因为赵铁柱工作效率不高,焊接组装一步手机需要 4 分钟,导致生产一部iPhone手机也得需要 4 分钟,从而拖累了整条生产线的生产效率。老板很生气,后果很严重,赵铁柱没干到一个月就被 fire 掉了。后面几个月,陆陆续续来了不少人:小黑、皮裤哥、红姐,都想试试这份工作,可惜干得还不如赵铁柱,挑战电子厂失败,早已提桶跑路。
老板招不到人,感觉又错怪了赵铁柱,于是决定升级生产线,并承诺加薪重新召回了赵铁柱。
老板找出了生产线的瓶颈:每道工序都是需要2分钟,只有赵铁柱这道工序耗时4分钟,老板错怪了这铁柱,这不是赵铁柱的原因,是因为这道工序太复杂。于是把这道工序进行了拆解为2道工序:焊接电路板和组装手机。焊接电路仍由赵铁柱负责,把电路板、显示屏、手机外壳组装成手机这道工序则由新招员工王建国负责。生产流水线优化后,赵铁柱焊接电路只需要2分钟,王建国组装也只需要 2 分钟,生产每部 iPhone 的时间由原来的 4 分钟缩减为 2 分钟,生产流水线的瓶颈解决了!
跟富士康流水线类似,优化CPU流水线也是提升CPU性能的有效手段。流水生产线存在木桶短板效应,我们只需要找出CPU流水线中的性能瓶颈,即耗时最长的那道工序,然后再进行细分、优化为更多的工序就可以了。每一道工序我们称为流水线的一级,流水线越深,每一道流水电路单元的执行时间就会变得越小,我们处理器的时钟周期就可以更短,从而可以通过提升CPU主频来提升CPU性能、提高工作效率。
在富士康流水生产线中,每道工序的最长耗时时间决定了整条生产线的吞吐率。在CPU内部也是如此,每个流水单元的执行时间(即时间延迟)决定了CPU流水线的性能。CPU流水线中的每一道电路单元由组合逻辑电路和寄存器组成,逻辑单路用来执行本道工序的逻辑运算,寄存器用来保存结果,并作为下一道工序的输入。
流水生产线是通过减少每一道工序的耗费时间来提升整条流水线效率的。在CPU内部也是如此,CPU内部的数字电路是靠时钟驱动来工作的,既然每条指令的执行时钟周期数不变,即执行每条指令需要3个时钟周期,但是我们可以通过缩短时钟周期的方法来提升效率,即减少每条指令所耗费的时间。减少时钟周期,也就是提升CPU主频,一个关键的制约因素就是CPU内部每一个执行单元的耗费时间。虽然说电信号在电路中的传播时间很快,可以接近光速,但是经过成千上万的晶体管,不停地信号翻转,还是会带来一定的时间延迟,这个时间延迟我们可以看做这道工作的执行时间。以上图为例,如果每个执行单元的延迟是 1.5 纳秒,那么你的时钟周期至少也得2纳秒以上,否则电路就会工作异常。如果驱动CPU工作的时钟周期是 2 纳秒,CPU的主频就是 500 MHz。现在的CPU流水线深度可以做到10级以上,流水线的每一级时间延迟可以做到皮秒级别,驱动CPU工作的时钟周期可以做到更短,因此可以把CPU的主频飙到 5 GHz 以上。
我们把5级以上的流水线称为超流水线结构。高性能的处理器,为了提升CPU主频,一般都会采用这种超流水线结构。Intel的 i7 处理器有16级流水线,AMD的速龙64系列CPU流水线为20级。史上具有最长流水线的是Intel的第三代奔腾四处理器,有31级的流水线。
想要提升CPU的主频,根本在于减少流水线中每一级流水的执行时间,消除木桶的短板效应,才能提升流水线的整体性能。解决方法有三个:一是优化流水线中各级流水线的性能,受限于当前集成电路的设计水平,这一步最难;二是依靠集成电路的制造工艺,更先进的纳米工艺,芯片面积越小,发热越小,更容易提升主频;三是不断地增加流水线,流水线越深,流水线的各级延迟就可以做得越小,更容易提高主频。
流水线是否越深越好呢?非也。流水线的本质是拿空间换时间,流水线越深,电路就会越复杂,需要更多的组合逻辑电路和寄存器,芯片面积也就越大,功耗也就随之上升了。拿功耗增长换来性能提升,在PC机和服务器上还行,但对于很多靠电池供电的移动设备的处理器来说就无法接受了,CPU设计人员需要在性能和功耗之间做一个很好的平衡。
流水线越深,就越能提升性能吗?也不一定。流水线是靠指令的并行来提升性能的,第一条指令还没有执行完,下面的第二条指令就开始取指、译码了。执行的程序指令如果是顺序结构,没有中断或跳转,流水线确实可以提高执行效率。但是当程序指令中存在跳转、分支结构时,下面预取的指令可能就要全部丢掉了,需要到要跳转的地方重新取指令执行。
BEQ R1, R2, here
ADD R2, R1, R0
ADD R5, R4, R3
...
here:
SUB R2, R1, R0
SUB R5, R4, R3
...
流水线越深,一旦预取指令失败,浪费和损失就会越严重,因为流水线中预取的几十条指令可能都要丢弃掉,流水线发生了停顿,无法按照预期继续执行,这种情况我们一般称之为流水线冒险(hazard)。在现在很多超流水线处理器中,为了避免这种情况出现,会采取各种各样的方法去避免这种情况,以免影响处理器的性能。--本文摘自《嵌入式C语言自我修养》e的标签处取SUB指令,流水线才能接着继续执行。
流水线越深,一旦预取指令失败,浪费和损失就会越严重,因为流水线中预取的几十条指令可能都要丢弃掉,流水线发生了停顿,无法按照预期继续执行,这种情况我们一般称之为流水线冒险(hazard)。在现在很多超流水线处理器中,为了避免这种情况出现,会采取各种各样的方法去避免这种情况发生,以免影响处理器的性能。--本文摘自《嵌入式C语言自我修养》