Cache Coherent的代价

我们都知道通过MESI类协议,CHI/ACE总线可以做到多Master缓存一致性,但是Cache为什么要有一致性?不一致又能怎么样呢?

Cache一致是说,CPU0和CPU1的CacheLine都有addr0(PA)的数据;CPU0写一下addr0,CacheLine改变之前,会触发CPU1 CacheLine变Invalid。

如果没有会发生什么呢?

CPU0和CPU1都Cache了addr0的数据,CPU0改掉了addr0的数据,但CPU1并不知道,然后CPU0给CPU1发了个内部中断,通知CPU1接收addr0的更改,结果CPU1看了看addr0,摇了摇头。。。

所以如果Cache没有一致性,每次需要通知到其他CPU addr0变化的时候,都需要Cache Flush,并且其他CPU如果一直在盯着addr0读,可能没有addr0重新load的机会,然后就一直看不到了。

所以Cache中最起码有一种类似表的机制,来记录各个CPU缓存了啥地址。

指令缓存有必要一致性吗?没有吧?都只读的。。。

只读数据段是不是也不是很必要一致性?

线程私有数据段有必要有一致性吗?好像也是可以无的吧?(比如说自己的堆栈,线程私有变量)

分一个地址段给指令、只读、线程私有的数据,是不是就可以走一个更简单的Cache。

那么设备呢?CPU和设备加上一致性难吗?

首先我们需要看一下Cache coherent会带给Cache的包袱:(下图是盗的,链接我贴了)

                                                                                      CPU Cache与缓存一致性协议MESI - 知乎

当CPU0要读addr0,它首先需要通知到其他所有CPU(我就举CPU1),然后CPU1查一查自己有没有addr0的副本

1. 有,可能独占可能share,CPU1的addr0状态变share,然后返回exclusive或share,然后CPU0读数据,这里是允许CPU0抢先读数据的(就是不用等CPU1返回,CPU0就读回数据来,等CPU1返回了再决定数据能不能用)

2. 有,被CPU1修改过,CPU1的addr0要flush出去,然后状态变share,然后返回modified,然后CPU0读数据,这里是不允许CPU0抢先读数据的(就是不用等CPU1返回,CPU0就读回数据来,等CPU1返回了就会发现,不能用,重读。这个时间超长,CPU1收到消息,然后flush,然后才会返回modify,然后CPU0才能重读)

3. 没有,CPU1不动,返回没有,CPU0读数据,,这里是允许CPU0抢先读数据的

CPU0无论如何都要等CPU1返回有没有,不过好消息是,只要返回的不是modify,CPU0抢先读回来的数据都是能用的。这对从ddr读数据最起码是个好消息,因为从ddr读数据,意味着其他CPU的Cache里面肯定不会有东西了。

当CPU0要写addr0,它首先需要通知到CPU1,然后CPU1查一查自己有没有addr0的副本

1. 有,CPU1自己invalid掉CacheLine,CPU0不关心CPU1的死活,通知CPU1的时候就是直挺挺的往下写。

2. 没有,没有就啥事儿没有,反正CPU0不关心CPU1的死活,通知CPU1的时候就是直挺挺的往下写。

事儿不是很多,但是,要注意,CPU对Cache的每一笔读/写都要广播出去哦!!!算算得多少电费,如果有128个CPU一起在一个总线上嗡嗡嗡的互相通知。。。啧啧啧。。。

大小核总归还是能做到Cache都一样,但是如果加上外设,,,啧啧啧。。。

CPU到外设的线可长着呢,latency也长着呢。

不说外设,就算是Die2Die之间的Cache Coherent,跨Die的latency,,,啧啧啧。。。真是不知道咋解决的。

那么原子操作呢,也是要有一个表记住哪位大哥做原子操作的吧,不过原子操作还好,一共CPU也没几个,不用记录很多条;不过最起码是1个CPU对应有1条嘛,128个CPU就是要记128条;好像也还可以。就算跟外设搞起原子操作,也问题不大,毕竟还是有个表记着。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值