就为了一个原子操作,其他CPU核心罢工了

资讯 来源:IT之家   阅读量:7314    2022-10-08 18:34

++问题

阿q,快点回来隔壁二车间的老虎说我们改了他们的数据,找上门来闹事

由于老k的突然出现,我不得不提前结束与小黑的交流,赶回CPU一号车间。

当我回来的时候,老虎立刻冲我大喊,你怎么了只花了几纳秒就给我改了数据

我听得迷迷糊糊,一遍又一遍地说:别着急,老虎我刚回来这是怎么回事先通知我一声,好吗

接下来,老k告诉了我事情的经过原来负责我们两个CPU车间的线程都在执行一个i++操作,我们都把I的值放在自己的缓存里完成后,我们没有通知对方,添加了两次,结果只有一次,导致数据不一致

原子操作

知道了事情的始末,我对你说:每个人执行的代码都是一样的,不能因此责怪我们。

好了,好了,先冷静下来你看,我们不知道你先去拿了这是不可原谅的吗再说,既然事情出了差错,我们就应该一起坐下来,想办法避免以后再出现这种问题,你说呢

老虎叹了口气,问道:那你告诉我你能做什么。

我继续说,你看,我们在执行i++这样的运算时不应该被打扰。

没被打扰。

对,比如你们二车间参观我的时候,我们一车间参观不了,只好等你参观后我们会回来,但这个非常简单的方法非常有用

虎子听后一愣,这不是锁吗难道要怪程序员在i++之前不锁吗

确实是锁定,但是程序员锁定这个简单的操作太麻烦了我们就在CPU内部处理吧

内部处理,你打算怎么实现,虎子问道

来,让我考虑一下,你问的是具体实施,我还没想到这一步。

这时,一旁的老k站了出来:我确实有办法找到公交局长他是总指挥,负责协调各车间使用系统总线访问内存他在中间协调应该不难

古语K惊醒梦中人,然后我们去找了公交局长后来我们研究出了一套解决方案:我们定义了一个叫原子操作的东西,意思是它是一个不可分割的动作谁想执行原子操作,总线控制器就给系统总线加一个LOCK#信号其他车间的人想要访问内存,必须等到原子操作指令执行完毕

我们把这个方案上报给了领导,很快得到了批准后来我们八个车间都是按照这个方案工作的程序员把i++之类的动作改成原子操作之后,问题就可以解决了

但实施一段时间后,各个车间开始大受其害:就因为一个车间要进行一次原子操作,就要求总线主管锁定系统总线,其他车间的人无法访问内存,无法工作,严重影响了工作效率。

抱怨就是抱怨,在没有更好的替代方案之前,生活还得继续。

缓存导致的问题

可是没过多久,数据不一致的情况再次出现。

这次不是加法的问题我们两个车间因为各自缓存的原因修改了变量值对方没有马上知道,误用了错误的价值观,酿成大错

阿q,上次的方法不错,但这次解决不了问题你又来找我了

你来得正是时候我只是想和你谈谈这件事

哦,对了,你想到破解的方法了吗。

这只是一些初步的想法问题的核心在于,现在我们公司每个车间都有自己的私有缓存,修改数据后更新内存时也不打招呼,缺乏联系机制

你点头了确实如此,所以我们需要建立一个联系机制,统一管理各个车间的缓存内容,对吗

高速缓存一致性协议MESI

很快,我们CPU的八大核心车间就这个问题召开了会议,取得了非常重要的成果。

我们走了一条新的专线,把八个核心车间连接起来,进行它们之间的信息沟通,这和CPU之外的总线系统是不一样的我们称之为片上总线

新线路铺设后,大家可以通过这条线路即时交流为了解决前面的问题,大家也制定了一套规则,叫做缓存一致性协议

规则规定了所有车间中的高速缓存单元——高速缓存线有四种状态:

已修改已修改

缓存行已被修改,与内存值不同如果其他CPU内核想要读取内存中的这些数据,它们应该在此之前将缓存行写回主存,并将状态更改为共享

独家的

缓存只在当前CPU核缓存中,和内存中的数据是一样的当其他CPU内核读取时,状态变为共享,如果当前CPU内核修改了它,它将被修改

共享的

缓存存在于多个CPU核的缓存中,与内存中的内容一致。

病人

缓存无效。

四种状态之间的转换如下:

按照这套规则,大家都不能像以前那样随便了当每个车间读写自己的缓存时,需要相互通信以避免使用过时的数据

此外,还规定如果一个内存区域被多个车间缓存,则不再允许多个车间同时修改缓存。

大会的另一个收获是,曾经被工坊们诟病的每一个原子操作都要锁总线,大家需要访问内存而不得不等待的问题得到了解决未来,总线控制器不再需要锁定总线,通过这种缓存一致性协议即可完成

从此,数据不一致的问题终于得到了根治,我们八个车间又可以愉快地工作了。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。

友情合作