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

时间:2019-04-29 13:47:48

标签: cpu x86-64 atomic instructions mesi

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

据说总体结果是变量只增加了一次,而两个内核都试图增加它(结果是两个)。因此,问题在于,如果在写操作期间,两个内核都请求对缓存行的排他访问(因此其他内核“等待”它们的修改,从而也获得了排他访问),为什么在该变量上存在数据竞争?

1 个答案:

答案 0 :(得分: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缓存将标记为M,CPU 1缓存将标记为I