内存屏障与互锁对内存缓存一致性定时的影响

本文关键字:内存 一致性 定时 影响 缓存 | 更新日期: 2023-09-27 18:12:56

简化问题:

与内存屏障相比,由互锁操作引起的内存缓存一致性(或"刷新"(的时间是否存在差异?让我们考虑C#中的任何互锁操作与线程。MemoryBarrier((。我相信有区别

背景:

我读到的关于内存障碍的信息很少——所有这些信息都对防止特定类型的内存交互指令重新排序有影响,但我找不到关于它们是否应该导致读/写队列立即刷新的一致信息。

事实上,我发现很少有消息来源提到,不能保证操作的即时性(只能保证防止特定的重新排序(。例如

维基百科:"然而,需要明确的是,这并不意味着在屏障完成时任何操作都将完成;只有完成操作的订单(当它们完成时(才有保证">

Freebsd.org(屏障是特定于硬件的,所以我想特定的操作系统无关紧要(:"内存屏障只是决定内存操作的相对顺序;它们不能保证内存操作的时间">

另一方面,互锁操作(定义为(会立即刷新所有内存缓冲区,以确保变量的最新值得到更新会导致内存子系统用该值锁定整个缓存行,以防止来自任何其他CPU/核心的访问(包括读取(,直到操作完成。

我是对的还是错的?

免责声明:

这是我最初的问题的演变,这里的变量新鲜度保证。NET(易失性与易失性读取(

第1版:修正了我关于Interlocked操作的语句-内联文本。

第2版:完全删除演示代码+它的讨论(因为有些人抱怨信息太多(

内存屏障与互锁对内存缓存一致性定时的影响

要理解C#互锁操作,您需要理解Win32互锁操作。

"纯"互锁操作本身只影响操作直接引用的数据的新鲜度。

但在Win32中,互锁操作过去意味着内存已满。我相信这主要是为了避免在新硬件上破坏旧程序。所以InterlockedAdd做两件事:互锁添加(非常便宜,不影响缓存(和全内存屏障(相当重的操作(。

后来,微软意识到这是昂贵的,并添加了每个操作的版本,没有或部分内存障碍。

因此,现在(在Win32世界中(几乎所有东西都有四个版本:例如,InterlockedAdd(完全围栏(、InterlockedAddAcquire(读取围栏(、InterlockedAddRelease(写入围栏(、纯InterlockedddNoFence(无围栏(。

在C#世界中,只有一个版本,它与"经典"的InterlockedAdd相匹配,后者也执行全内存围栏。

简短回答:CAS(Interlocked(操作一直是(而且很可能会(最快的缓存刷新器。

背景:-CAS操作在硬件中由单个不可理解的指令支持。与线程调用内存屏障相比,内存屏障可以在放置屏障之后但在执行任何读/写之前进行交换(因此仍然满足屏障的一致性保证(。-CAS操作是大多数(如果不是全部的话(高级同步构造(互斥对象、信号、锁——看看它们的实现,你会发现CAS操作(的基础。如果它们不能保证即时的跨线程状态一致性,或者如果有其他更快的机制

,它们就不太可能被使用

至少在英特尔设备上,一堆机器代码操作可以以LOCK前缀作为前缀,这确保了以下操作被视为原子操作,即使底层数据类型无法一次性安装在数据总线上,例如,LOCK REPNE SCASB将扫描一个字节串以查找终止零,并且不会被其他线程中断。据我所知,Memory Barrier构造基本上是一个基于CAS的旋转锁,它会导致线程等待某些条件得到满足,例如没有其他线程要做任何工作。这显然是一个更高级别的构造,但毫无疑问,其中有一个条件检查,它可能是原子的,也可能是CAS保护的,当你达到内存障碍时,你仍然要支付缓存线的价格。