Multithreading 为什么CompareAndSwap指令被认为是昂贵的?

Multithreading 为什么CompareAndSwap指令被认为是昂贵的?,multithreading,synchronization,multicore,Multithreading,Synchronization,Multicore,为什么CompareAndSwap指令被认为是昂贵的 我在书中读到: “记忆障碍非常昂贵,大约相当于 昂贵的原子比较数据集() 指示。” 谢谢 这是因为它们为使操作原子化引入了额外的开销。底层平台必须抑制优化(如缓存)并暂停线程执行,以简化障碍,这需要大量额外的工作。当额外的活动正在进行时,线程无法执行,因此整个程序会产生一个时间延迟。一般来说,原子操作是昂贵的,因为它们需要跨CPU同步。允许对缓存数据执行“正常”操作,从而提高速度。例如,在2 cpu系统上: 线程1 while (1) x++

为什么CompareAndSwap指令被认为是昂贵的

我在书中读到:

“记忆障碍非常昂贵,大约相当于 昂贵的原子比较数据集() 指示。”


谢谢

这是因为它们为使操作原子化引入了额外的开销。底层平台必须抑制优化(如缓存)并暂停线程执行,以简化障碍,这需要大量额外的工作。当额外的活动正在进行时,线程无法执行,因此整个程序会产生一个时间延迟。

一般来说,原子操作是昂贵的,因为它们需要跨CPU同步。允许对缓存数据执行“正常”操作,从而提高速度。例如,在2 cpu系统上:

线程1

while (1) x++;
while (1) atomicIncrement(&x);
线程2

while (1) x++;
while (1) atomicIncrement(&x);
由于增量不是一个原子操作或受内存屏障保护,因此其结果几乎没有定义。您不知道x将如何递增,或者它甚至可能会损坏

线程1

while (1) x++;
while (1) atomicIncrement(&x);
线程2

while (1) x++;
while (1) atomicIncrement(&x);
现在,您正试图获得定义良好的行为-无论顺序如何,x都必须逐个递增。如果两个线程在不同的CPU上运行,它们必须减少允许的缓存量,或者“比较注释”,以确保发生合理的事情


这种额外的开销可能相当昂贵,这也是原子操作缓慢的普遍原因。

我想我在我的书中找到了答案:

每个getAndSet()都广播到总线。因为 所有线程都必须使用总线与进行通信 内存中,这些getAndSet()调用延迟所有线程(核心), 即使是那些没有等待锁的人

更糟糕的是,getAndSet()调用强制其他 处理器放弃自己的缓存副本 锁,所以每一条旋转的线都会遇到 缓存几乎每次都未命中,并且必须使用 总线获取新的但未更改的值。

此处的“昂贵”是非常相关的。与硬盘访问相比,这绝对是微不足道的。但是RAM总线的速度跟不上现代CPU的速度,与CPU内部的算术运算相比,直接访问RAM(即非缓存)是相当昂贵的。从RAM中获取
int
所需的时间是添加两个寄存器所需时间的50倍

因此,由于内存屏障基本上强制直接RAM访问(可能用于多个CPU),它们的成本相对较高。

“CAS与普通存储器没有明显区别。有关CAS的一些错误信息可能源于最初的lock实现:cmpxchg(CAS)在英特尔处理器上。lock:前缀导致声明lock#信号,从而获得对总线的独占访问。这当然不能扩展。lock:cmpxchg的后续实现利用缓存一致性协议(通常是基于snoop的MESI)而不声明lock#

“内存障碍非常昂贵,大约与原子比较数据集()指令一样昂贵。”

这是千真万确的。
例如,在x86上,多处理器系统上的正确CAS具有锁定前缀。
锁定前缀会导致完全的内存障碍:

“…锁定操作序列化所有未完成的加载和存储操作(即,等待它们完成)。”。。。“锁定操作是相对于所有其他内存操作和所有外部可见事件的原子操作。只有指令获取和页表访问才能传递锁定的指令。锁定指令可用于同步一个处理器写入和另一个处理器读取的数据。”-,第8.1.2章

实际上,在x86/x64和x86/x64上,内存屏障都是作为虚拟的
锁或
锁和
实现的。
在x86上,CAS会产生一个完整的内存屏障

在PPC上则不同。可以使用一对将内存操作数加载到寄存器中,然后在目标位置没有其他存储的情况下将其写回,或者在有存储的情况下重试整个循环。LL/SC可以中断。
它也不意味着自动全围栏。
在不同的体系结构上,性能特征和行为可能会非常不同。

但是,再说一遍,a不是CAS。

我认为这与指令有关,指令迫使其他内核从内存重新读取并更新其缓存(或其他内容)。原子学可能需要跨CPU同步,但这不是所有情况下的要求。请阅读《内存一致性和一致性入门》一书的第3.9节。