0

我正在阅读有关 MESI 协议的内容,如果我们对每个写入操作都具有独占访问权限,从而导致其他内核缓存中的缓存行无效,那么为什么会出现数据竞争?在这个例子中:

CYCLE # CORE 1                        CORE 2
0   reg = load(&counter);   
1   reg = reg + 1;                reg = load(&counter);
2   store(&counter, reg);         reg = reg + 1;
3                                 store(&counter, reg);

据说总体结果是变量仅增加一次,而两个内核都尝试增加它(结果预计为两个)。所以问题是,如果在写入操作期间,两个内核都请求独占访问缓存行(因此其他内核“等待”轮到他们修改并因此也获得独占访问)为什么该变量存在数据竞争?

4

1 回答 1

4

如果我没看错的话,MESI 在这里只是一个红鲱鱼:

0   reg = load(&counter);   

counter现在已被加载到 CPU 的寄存器中。

1   reg = reg + 1;                reg = load(&counter);

第一个处理器增加了值,第二个处理器加载了旧的。

2   store(&counter, reg);         reg = reg + 1;

第一个处理器存储值,第二个处理器增加其过时的值。

3                                 store(&counter, reg);

第二处理器存储基于过期值的计算结果。

到目前为止应该很清楚。现在如果添加 MESI 状态将如何改变:

0   reg = load(&counter);   

counter位于 CPU 1 缓存中,标记为E.

1   reg = reg + 1;                reg = load(&counter);

counter仍然驻留在 CPU 1 缓存中,但也被加载到 CPU 2 缓存中。所以两个缓存行都需要标记为S

2   store(&counter, reg);         reg = reg + 1;

现在counter被存储回缓存中。因此 CPU 1 缓存需要标记为M,而 CPU 2 缓存无效(标记为I)。

3                                 store(&counter, reg);

由于 CPU 2 缓存失效,因此需要在store操作发生之前对其进行更新,这反过来又需要 CPU 1 缓存在之前(当然)写回内存。

但是现在所做的一切,reg仍然是根据过时的值计算的值,并且仍然覆盖缓存中的(现在更新的)值......

添加最后一个细节:操作后,CPU 2 cache 会被标记M,CPU 1 cache 会被标记I

于 2019-04-29T14:33:06.530 回答