CAS指令如何保证原子性

Fro*_*art 3 assembly multithreading atomic

根据Wiki,CAS 做这样的事情:

function cas(p : pointer to int, old : int, new : int) returns bool {
    if *p ? old {
        return false
    }
    *p ? new
    return true
}
Run Code Online (Sandbox Code Playgroud)

好吧,在我看来,如果多个处理器将尝试使用相同的参数执行 CAS 指令,则可能会同时进行多次写入尝试,因此无论如何这样做都不安全。

我哪里错了?

Pet*_*des 5

同时来自多个内核的原子读-比较-写指令确实会相互竞争,但这取决于硬件来解决这个问题。 原子 RMW 指令的硬件仲裁在现代 CPU 中是真实存在的,它提供了一定程度的公平性,因此一个线程旋转lock cmpxchg不能完全阻止其他线程做同样的事情。(虽然这是一个糟糕的设计:最好在获取负载上旋转,并且只有在成功时才执行 CAS)

无法保证它们发生的顺序,这就是为什么您需要仔细设计算法,以便正确性仅取决于比较和交换的原子性。(ABA 问题是一个常见的陷阱)。


顺便说一句,整个伪代码块作为单个原子操作发生。对于硬件来说,将读-比较-写或读-修改-写作为单个原子操作进行要困难得多,而不仅仅是存储,MESIF/MOESI 处理得很好。

你确定吗?我认为这样做是不安全的,因为例如,x86 不保证非对齐 DWORD 的写入原子性

lock cmpxchg无论对齐如何,都使操作具有原子性。对于未对齐,它可能会慢很多,特别是在缓存行拆分时,原子修改单个缓存行是不够的。

另请参阅x86上的原子性,其中我解释了操作是原子性的含义。


归档时间:

查看次数:

887 次

最近记录:

9 年,5 月 前