简化问题:
与内存屏障相比,Interlocked操作导致的内存缓存一致性(或者#34;刷新")的时间是否存在差异?让我们在C#中考虑 - 任何互锁操作与Thread.MemoryBarrier()。我相信存在差异。
背景
我读了很少关于内存障碍的信息 - 所有对预防特定类型的内存交互指令重新排序的影响,但是我无法找到关于它们是否应该立即导致立即刷新的一致信息读/写队列。
我实际上发现很少有消息来源提到不保证操作的即时性(只保证特定的重新排序是有保障的)。 E.g。
Wikipedia: "但是,要明确的是,这并不意味着在屏障完成时任何操作都会完成;只有完成操作的订购(当它们完成时)才能得到保证"
Freebsd.org(障碍是硬件特定的,所以我猜一个特定的操作系统并不重要):"内存障碍只是确定内存操作的相对顺序;他们不保证记忆操作的时间安排"
另一方面,Interlocked操作 - 来自其定义的会导致立即刷新所有内存缓冲区以保证更新的最新值已更新导致内存子系统使用该值锁定整个缓存行,以防止从任何其他CPU /核心访问(包括读取),直到操作完成。
我是对还是错了?
声明:
这是我原来问题的演变Variable freshness guarantee in .NET (volatile vs. volatile read)
EDIT1: 修复了关于互锁操作的声明 - 内联文本。
EDIT2: 完全删除演示代码+它的讨论(因为一些人抱怨信息太多)
答案 0 :(得分:0)
简短回答:CAS(Interlocked)操作已经(并且很可能会)成为最快的缓存刷新器。
背景: - 通过单个不可中断指令在HW中支持CAS操作。与线程调用内存屏障相比,线程调用内存屏障可以在放置屏障后立即交换,但在执行任何读/写之前(因此仍然满足屏障的一致性)。 - CAS操作是大多数(如果不是全部)高级同步构造的基础(互斥体,sempahores,锁 - 查看它们的实现,你会发现CAS操作)。如果它们不能保证立即跨线程状态一致性或者是否存在其他更快的机制,则不太可能使用它们
答案 1 :(得分:0)
至少在英特尔设备上,一堆机器码操作可以使用LOCK前缀作为前缀,这样可确保将以下操作视为原子操作,即使基础数据类型不能一次性适应数据总线例如,LOCK REPNE SCASB将扫描一串字节以获得终止零,并且不会被其他线程中断。 据我所知,Memory Barrier构造基本上是一个基于CAS的自旋锁,它使一个线程等待满足某些条件,例如没有其他线程有任何工作要做。这显然是一个更高层次的构造,但在那里不要错误,那里的条件检查,它可能是原子的,也可能受CAS保护,你还在继续在达到内存障碍时支付缓存行价格。