内存屏障和缓存刷新
Posted
技术标签:
【中文标题】内存屏障和缓存刷新【英文标题】:memory barrier and cache flush 【发布时间】:2012-07-02 05:33:13 【问题描述】:是否存在即使使用缓存刷新也实现了内存屏障的拱门?我读到内存屏障仅影响 CPU 重新排序,但我阅读了与内存屏障相关的语句:确保所有 cpu 都能看到该值...,但对我来说,这意味着缓存刷新/失效。
【问题讨论】:
【参考方案1】:内存屏障的确切影响取决于具体的架构
CPU 采用了可能导致乱序的性能优化 执行。内存操作(加载和存储)的重新排序 通常在单个执行线程中不会被注意到,但是 在并发程序和设备中导致不可预测的行为 司机除非小心控制。订购的确切性质 约束取决于硬件,并由架构的定义 内存排序模型。一些架构提供了多重障碍 用于执行不同的排序约束。
http://en.wikipedia.org/wiki/Memory_barrier
当前的 Intel 架构确保所有 CPU 的自动缓存一致性,无需显式使用内存屏障或缓存刷新指令。
在对称多处理器 (SMP) 系统中,每个处理器都有一个本地 缓存。内存系统必须保证高速缓存的一致性。虚假分享 当不同处理器上的线程修改变量时发生 驻留在同一缓存行上。这会使缓存行无效,并且 强制更新,这会损害性能。
http://software.intel.com/en-us/articles/avoiding-and-identifying-false-sharing-among-threads/
【讨论】:
您确定缓存一致性保证吗?我想虚假分享话题不适合问这样的问题。我相信存在必须处理的存储缓冲区和失效队列以允许执行依赖于缓存状态。 非常肯定,是的。这里简单介绍一下 Intel 使用的协议en.wikipedia.org/wiki/MESIF_protocol 在这种情况下你错了。在将存储缓冲区中的值写入缓存之前,缓存一致性协议不会轮流执行。同样,如果项在失效队列中处于未决状态,则缓存状态不一致。 参见例如fgiesen.wordpress.com/2014/07/07/cache-coherency。更多关于store buffer、invalidation queue、memory barrier的参考搜索论文。 从该参考资料来看,大多数普通硬件都使用窥探协议,以确保多缓存一致性。As soon as one core writes to a memory location, the other cores know that their copies of the corresponding cache line are now stale and hence invalid.
【参考方案2】:
在几乎所有现代架构中,缓存(如 L1 和 L2 缓存)都由硬件确保一致。无需刷新任何缓存即可使内存对其他 CPU 可见。
可以假设一个系统在硬件中缓存不一致,但它看起来与当前运行 Windows 和 Linux 等操作系统的系统完全不同。
这些架构需要内存屏障来做三件事:
CPU 可能会预取因在另一个内核上的写入而无效的读取。必须防止这种情况。 (虽然在 x86 上,这在硬件中是被阻止的。预取被锁定到 L1 缓存行,所以如果另一个 CPU 使缓存行无效,预取也会失效。)
CPU 可能会“发布”写入,但尚未将它们放入其 L1 缓存中。这些写入必须至少完成到 L1 缓存。
CPU 可能会在内存屏障的一侧重新排序读取和写入,而在另一侧进行读取和写入。根据内存屏障的类型,必须禁止其中一些重新排序。 (例如,read x; read y;
不能确保读取按此顺序进行。但 read x; memory_barrier(); read y;
通常会这样做。)
【讨论】:
我并不是说我必须显式地使缓存无效,但在硬件中(在某些拱门上)内存屏障甚至意味着缓存无效。我现在从这里读到它:linuxjournal.com/article/8212 对于 ALPHA(一个非常古老的拱门), smp_wmb() 意味着缓存失效。 我猜你错过了削弱缓存一致性保证的存储缓冲区和失效队列的概念。 @Ucho OP 已经明白这一点。 “我读到内存屏障只影响 CPU 重新排序”。存储缓冲区和失效队列是 CPU 中的重新排序机制,对缓存一致性保证没有影响。这就是 CPU 重新排序的方式。这些是受内存障碍影响的东西。 @DavidSchwartz 如果 OP 理解这些概念,就没有问题。直到缓冲区或队列得到满足,缓存是不一致的,所以没有刷新就不能依赖一致性。 @Ucho 我不明白为什么。如果 CPU 重新排序读取或写入,刷新缓存有何帮助?以上是关于内存屏障和缓存刷新的主要内容,如果未能解决你的问题,请参考以下文章