带有写缓冲区的多处理器如何保持顺序一致性? 据我所知,在单处理器中,如果缓冲区是FIFO并且缓冲区提供了对要在主存储器上写入的待处理元素的读取,则它保持一致性。 但它如何在议员中发挥作用?我认为如果处理器将商店放在他的缓冲区中,另一个处理器就无法读取它,我认为这会破坏顺序的一致性。
它如何在每个线程具有写缓冲区的多线程环境中工作?它还打破了连续的一致性?
答案 0 :(得分:0)
您提到:
通常,CPU只能看到随机访问;存储器总线被顺序访问的事实对CPU本身是隐藏的,因此从CPU的角度来看,这里没有涉及FIFO。
在SMP现代机器中,有所谓的监听控制单元,可以监视内存传输,并在必要时使RAM的缓存副本无效。因此,有专门的硬件来确保数据是同步的。这并不意味着它实际上是同步的 - 总是有多种方法来获取无效数据(例如,在另一个CPU内核发生变化之前已经将一个内存值加载到寄存器中它),但这就是你所得到的。
此外,多线程基本上是一个软件概念。因此,如果您需要同步软件FIFO,则需要使用正确的锁定机制。
答案 1 :(得分:0)
我假设这里是 X86。
存储缓冲区中的存储本身不是问题。例如,如果 CPU 只执行存储,并且存储缓冲区中的所有存储都按顺序退出,那么它的行为将与没有存储缓冲区的处理器完全相同。对于 SC,不需要保留实时顺序。
并且您已经指出处理器将按顺序在存储缓冲区中看到自己的存储。违反 SC 的部分是当存储后跟加载到不同地址时。
想象一下
A=1
r1=B
然后没有存储缓冲区,首先将 A 的存储写入缓存/内存。然后将从缓存/内存中读取 B。
但是对于存储缓冲区,B 的负载可能会超过 A 的存储。因此,在将 A 的存储写入缓存/内存之前,负载将从缓存/内存中读取。
SC 与存储缓冲区中断的典型示例是 Dekkers 算法。
lock_a=1
while(lock_b==1){
if(turn == b){
lock_a=0
while(lock_b==1);
lock_a=1
}
}
因此在顶部您可以看到 lock_a=1
的存储,然后是 lock_b
的负载。由于存储缓冲区,这两个线程可能会被重新排序,因此 2 个线程可能会进入临界区。
解决这个问题的一种方法是在加载和存储之间添加一个 [StoreLoad] 栅栏,它可以防止在存储缓冲区被耗尽之前执行加载。这样SC就恢复了。
注 1:存储缓冲区是每个 CPU;不是每个线程。
注意 2:存储(和加载)缓冲区在缓存之前。