CPU摸鱼被抓,上了一个新技术!
The following article is from 编程技术宇宙 Author 轩辕之风O
第一时间收到文章更新
作者 | 轩辕之风
我叫阿Q,是CPU一号车间里的员工,我所在的这个CPU足足有8个核,就有8个车间,干起活来杠杠滴。
我们CPU的任务就是执行程序员编写的程序,只不过程序员编写的是高级语言代码,而我们执行的是这些代码被编译器编译之后的机器指令。
那一天,我正在忙活着···
“阿Q,工作时间你怎么在摸鱼啊!”,领导突然到访,吓得我一哆嗦。
“领导,我正在执行的这条指令,需要从内存读取数据,这您是知道的,内存那家伙可慢了,所以我只好等着,这可不是摸鱼哦···”,我小心地解释到。
领导眉头紧锁,指着一片电路问道:“这些是做什么的,怎么没在工作?”
“那是读取指令的电路”
“旁边那些呢”
“那是指令译码的电路,我手里这条指令还没执行完,现在还轮不到它们工作”
“反正也是闲着,就不能提前处理下一条指令吗?”,领导问道。
“不行啊,我们一直都是一条指令处理完成才处理下一条指令”
“这些电路单元闲着有点浪费啊,可惜了”,领导嘴里念叨着离开了我们一号车间,留下不知所措的我呆在原地。
指令流水线
没过几天,领导找我们几个车间的代表开了个会。
会上,领导问道:“各位,咱们执行指令的效率能不能提一提,竞争对手快追上我们了”
“这怎么提啊,我们干活够卖力的了”
“是啊,也没有划水偷懒”
各车间代表七嘴八舌地说到。
“还说没有划水?我最近去各车间巡视,经常发现有人摸鱼”
一听这话,大家都沉默,我也羞愧地低下了头。
领导接着说道:“我在想啊,咱们现在执行指令的过程存在不少的资源浪费,大家能不能别等一条指令执行完再执行下一条,而是提前执行下一条”
这话一出,在场各车间的代表都满脸问号。我们平时都是一条一条地执行指令,怎么还能提前执行后面的指令呢,这简直有点不可思议。
见大家一脸茫然,领导接着说道:“咱们现在执行指令的过程其实是分了好几个步骤的,不同的步骤需要用到的电路设备基本上是不一样的,在执行后面步骤的同时,前面步骤所用到的电路就可以腾出来用于处理后面的指令了”
就在我还有些似懂非懂时,二号车间小虎站起来说道:“我明白了!”
领导露出了满意的笑容,问道:“说说看,你明白什么了”
小虎转身来到一旁的画板上,画了一张图:
“大家请看,我们平时执行指令,差不多四个主要的步骤:读取指令、指令译码、指令执行、数据回写。在第一条指令进入指令译码的步骤时,负责读取指令的电路模块就闲下来了,这时可以用来读取下一条指令,提前节省了时间。等到第一条指令进入执行的步骤时,指令译码的电路就能用来处理第二条指令,而读取指令的电路就能用来读取第三条指令,以此类推!”,小虎得意的说到。
“妙啊,妙啊!”,我也忍不住称赞道:“整个过程就像一条流水线一样,一环扣一环!这效率肯定能提升不少”
“流水线?这个名字好,要不咱们就把这项技术叫做指令流水线吧!”,领导说到。
不久,咱们CPU各个车间就开始正式推行这项技术,把原来执行指令的过程流水线化。
在我们一号车间又增加了一些人手:负责指令读取的小A、负责指令译码的小胖,负责结果回写的老K,至于我嘛,就负责具体的指令执行。
流水线的级数
用上了流水线之后,我们CPU的工作性能一下有了非常明显的提升,甩开了竞争对手一大截,领导高兴坏了。
但还没高兴太久,不知道谁走漏了消息,竞争对手CPU们也知道了这项技术,也用上了指令流水线,我们的差距又一次缩小了。
领导又一次召开会议。
“现在该怎么办?大家想想办法啊”
会场一度陷入了沉默,过了一会儿,六号车间的代表小六才站起来发言:“领导,我有一个办法”
“什么办法?”
小六润了润嗓子说道:“我先问大家一个问题,在我们没有使用指令流水线技术的时候,假设执行一条指令需要4个步骤,每个步骤需要1ns,那执行完一条指令总共需要多少时间?4条指令全部执行完又需要多少时间呢?”
“一个步骤1ns,一条指令总共4个步骤就是4ns,4条指令就是16ns,这也太简单了吧”,二号车间小虎说到。
“没错,那用上流水线以后呢?”
“让我想想,用了流水线技术以后,从第4ns开始,每过1ns就会有1条指令从流水线上完成,完成上面4条指令,总共只需要7ns,比原来省了一半的时间。”
“说的没错,大家发现没有,如果我们把执行步骤拆的再细一些,每个小步骤需要的时间更短一些,这样流水线的深度就会更深一些,流水线中容纳的指令也就越多,性能就会变得更高。”,小六激动的说到。
领导也听得有些糊涂,打断问道:“等等,你慢一点,我没太明白”
小六继续说道:“比如从现在的4个步骤,拆成8个更小的步骤,每个小步骤需要的时间减半为0.5ns,这样一来,流水线跑起来后,每隔0.5ns的时间就会有一条指令完成,比4个步骤的情况更快了!“
“妙啊!妙啊!”,领导忍不住鼓掌说道:“就这么干”
我总觉得哪里不太对劲,却一时也说不上来。
回去之后,我们就进行升级改造,将现在的四级流水线,改造成八级。
你还别说,效果还真是立竿见影,将指令执行过程拆分得更细以后,流水线中容纳的指令数变得更多了,进一步减少了CPU电路资源的浪费,执行性能比以前更强了。
但没过多久,竞争对手CPU也把流水线级数增加了,而且比我们的还多,这可急坏了领导。
没有办法,我们也只好再一次提升流水线级数来应对。
就这样双方你来我往,我们玩起了流水线级数大战,最疯狂的时候,我们把流水线级数做到了三十级。
终于,我们搞出了事情。
我们把一条指令的执行过程拆分的越来越细,虽然是提高了资源的利用率,但每个小步骤之间都需要做好交接,就需要增加很多额外的电路设备。
步骤之间交接不仅有额外的时间开销,增加的电路设备也会产生额外的功耗。
流水线级数到了一定深度后,发现性能没有增加反而下降了,而且功耗越来越大,风扇都要疯狂转起来给我们降温。
看来这流水线级数也不是越多越好啊!我们又主动降低了流水线级数,在性能和功耗上选择了一个平衡点。
流水线里的冒险
不仅如此,我们在使用指令流水线的过程中,也渐渐地发现了一些其他问题。
有时候,我执行到一些指令,需要从内存读取数据到寄存器中。不巧的是,负责读取指令的小A也准备从内存中读取后面的指令,这同一时间咱俩都要访问内存,都要使用访存电路,这下尴尬了,搞得流水线只好停顿下来等待,等我用完了小A再用,白白浪费了时间。
还有的时候,我执行到一些指令,所需要的数据来自于前一条指令计算的结果,可流水线中前一条指令还没有结束,结果还拿不到,流水线只好又停顿下来等待。
这都还不算啥,更要命的是,遇到了有分支的时候,根本不知道要去把哪个分支的指令加入流水线中处理。
于是,我们把这些问题都集中反馈了上去,后来我发现不仅仅是我们车间,其他车间也遇到了这些问题。
大家把这些问题叫做流水线里的冒险,还给这三种问题分别取了三个名字:
结构冒险 :流水线中出现硬件资源竞争
数据冒险:流水线中后面的指令需要等待前面指令完成数据的读写
控制冒险:流水线需要根据前面指令的执行结果来决定下一步去哪执行
一时之间大家都没有什么好的办法,遇到这些问题就只好让流水线停顿下来等待,等待前面的指令完成,再继续工作。
但不断追求性能提升的领导,肯定不会放任这几个问题不管,又会想出什么样的应对办法呢?
为什么编程更关注内存而很少关注CPU? 印度也开始自研 CPU ,5nm工艺、功耗是i9好几倍 面试官:如何写出让 CPU 跑得更快的代码? 五年经验的前端社招被问:CPU 和 GPU 有什么区别? 可怕!CPU暗藏了这些未公开的指令!