本文来自微信公众号:编程技术宇宙 (ID:xuanyuancoding),作者:轩辕之风
自我介绍
我叫阿 Q,是 CPU 一号车间里的员工,我所在的这个 CPU 足足有 8 个核,就有 8 个车间,干起活来杠杠滴。
我所在的一号车间里,除了负责执行指令的我,还有负责取指令的小 A,负责分析指令的小胖和负责结果回写的老 K。
CPU 的每个车间都有一堆箱子,人们把这些箱子叫做寄存器,我所在的一号车间也不例外,我们每天的工作就是不断执行指令,然后折腾这些箱子,往里面存东西取东西。
由于我们四个人的出色工作,一号车间业绩突出,在年会上还多次获得了最佳 CPU 核心奖呢。
缓存
我们每天都需要跟内存打交道,不过由于内存这家伙实在太慢了,我们浪费了很多时间等待他给我们数据传输。
终于有一天,上面给我们下了命令,说竞争对手 CPU 的速度快赶上我们了,让我们想办法提升工作效率。这一下可难倒了我们,我们平时干活绝没有偷懒,要怪只能怪内存那家伙,是他拖了我们后腿。
一天晚上,我们哥四个在一起聚餐,讨论起上面的这道命令来,大家都纷纷叹气。
就在一筹莫展之际,老 K 提出了一个想法:“兄弟们,我发现了一个现象,咱们和内存打交道的时候,如果访问了某个地址的数据,它周围的数据随后也大概率会被访问到”,说到这里,老 K 停顿了一下。
我一边听一边想着,小 A 倒是先开口:“然后呢?你想表达什么意思?”
老 K 继续说道:“咱每次数据都找内存要,太慢了,我寻思在咱们车间划一块区域,结合我发现的那个现象,以后让内存一次性把目标区域附近的数据一起给我们,我们存在这块区域,后面在需要用到的时候就先去这里找,找不到再去找内存要,岂不省事?”
听老 K 这么一描述,感觉靠谱,我也赶紧附和:“好办法!你们看啊,这内存老是拖咱后退,但是这家伙一时半会也快不起来,要不咱先用这招试试,看看能不能加快一点工作效率,给上面也有个交代。”
说干就干,我们很快就付诸实践了,我们还给这技术取了个名字叫缓存,效果居然出奇的好,后来为了进一步优化,我们还把缓存分为了两块,一块离寄存器很近叫一级缓存,剩下的叫二级缓存。一级缓存中进一步分了指令缓存和数据缓存两块。
我们车间的工作效率那是飞速提升,但不知道是谁走漏了风声,其他几个车间也知道了这项技术,纷纷效仿。
这天,为了业绩,我们决定再加第三级缓存,这次把空间弄大点,不过咱们车间地盘有点局促,放不下,我们偷偷给上面领导反馈了这事儿,想让领导帮我们协调一下。
领导倒是同意了,不过告诉我们他得一碗水端平,平衡各车间的利益。但是咱厂里空间也有限,不可能给每个车间都分配那么大的空间,于是决定由厂里统一安排一块大的区域,让各个车间来共享。没有办法,我们也只好同意了。
现在,我们用上了三级缓存技术,内存那家伙拖后腿的现象缓解了不少,相当部分时间我们都能从这三级缓存里面找到我们需要的数据。
乱序执行
随着技术的发展,咱们 CPU 工厂的工作性能也是不断攀升,慢慢的,我们几个又开始闲下来了,因为我们实在太快了,尽管有了缓存,但我们还是有了不少闲暇时间。
这天我还是像往常一样,小 A 取指令去了,我们知道这得要点时间,于是我和小胖还有老 K 我们仨斗起了地主。
打了好几把,小 A 才气喘吁吁的回来,“小胖,该你去指令分析了,你起来让我来打几把”。小胖赶紧起身干活,换上了小 A 上桌。
就这样我们几个轮流工作,一直保持着三个人的斗地主牌桌。
没想到的是,没过多久,厂里领导过来视察了,正好撞见我们几个打牌,狠狠的训斥了我们一顿。
“你们几个上班时间玩得挺嗨啊”,领导的脸拉的老长。
“领导,我们没有偷懒,这取指令、译码、执行、回写几个步骤都得分步执行,但是我们工作太快,存储器跟不上我们,我们等得无聊打发时间嘛”,我上前解释到。
“干等着你们也可以提前做一些后面的准备工作嘛,不要浪费时间,让生产效率更上一层楼”,领导说完就离开了,留下我们几个面面相觑。
不过领导的一番话倒是如一记重锤敲在我的头上,对啊,我们有这打牌的时间不如提前把后续指令的准备工作先做了,肯定能提升不少效率呢!
我开始组织兄弟几个商讨方案,“兄弟们,我们最主要的时间都浪费在等待内存数据上了,如果我们能在等待的时间里把后续指令需要的数据提前准备到缓存中来,那可就节约不少时间了,不用每次都等那么久。”
老 K 听后很赞赏我的思路,并补充到:“不仅是准备工作,像有些指令,比如加法,如果参与加法的数据不依赖前面指令的结果,咱们完全可以提前把这加法指令执行了嘛,把结果保存在缓存中,等真正轮到这条指令执行的时候,再把缓存中的结果写到内存中,这不也是节约了时间吗”
大家开始头脑风暴起来,原来可以做的事情还这么多,之前光想着等靠要,现在要主动出击了,因为打乱了顺序提前会执行后面的指令,我们把这个技术叫做乱序执行.
“这次大家要保密哦,不能让隔壁车间知道咱们的这次讨论内容”,会议结束前,我提醒大家。
分支预测
按照这次会议讨论的结果,咱们第二天准备实行,不过刚一开始,就遇到了麻烦。
按照计划,我们在空闲时间里,会提前把后续要执行的指令能做的工作先做了,但麻烦的是我们遇到了一条判断指令,因为不知道最终结果是 true 还是 false,我们没法知道后续是应该执行分支 A 的指令还是分支 B 的指令。不敢轻举妄动,怕一会做了无用功。
大家只好放弃了提前做准备工作的想法,还是一步步来。
不过很快我们发现,我们经常执行到这个判断指令,而且每次结果都是去执行 A 分支,从没有去过 B 分支。
于是我们几个又商量,发明了一种叫分支预测的技术,遇到分支跳转时,按照之前的经验,如果某个分支经常被执行,那后续再去这个分支的概率一定很大,那这样咱们预测后面会去到这个分支,就提前把这个分支后面指令能做的工作先做了。
果然,用上了分支预测和乱序执行后,我们车间的效率又狠狠的提升了一把,在工厂的集体大会上又一次表扬了我们,并且把我们的先进技术向全厂推广。
未完待续・・・・・・
彩蛋
然而幸福的日子没过太长,我们就因为这两项技术闯下了弥天大祸。
那天,我们还是如往常一般工作,可不久发现我们的分支预测频频出错,提前做的准备工作也屡屡白费,很快,我们发现出事儿了・・・・・・
预知后事如何,请关注后续精彩・・・・・・
往期热门回顾
哈希表哪家强?几大编程语言吵起来了!
内核地址空间大冒险 4: 线程切换
震撼!全网第一张源码分析全景图揭秘 Nginx
一个整数+1 引发的灾难
一网打尽!每个程序猿都该了解的黑客技术大汇总
看过无数 Java GC 文章,这 5 个问题你也未必知道!
一个 Java 对象的回忆录:垃圾回收
谁动了你的 HTTPS 流量?
路由器里的广告秘密
一个 HTTP 数据包的奇幻之旅
我是一个流氓软件线程
本文由LinkNemo爬虫[Echo]采集自[https://www.ithome.com/0/644/626.htm]