如果在独占缓存访问期间发生写操作,为什么会出现数据竞争?

If write operation happens during exclusive cache access why is there data race?

我正在阅读有关 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);

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

如果我没看错的话,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 缓存将被标记为 M 和 CPU 1 缓存将被标记为 I.