内存壁垒会强制缓存一致性吗? [英] Memory barriers force cache coherency?

查看:103
本文介绍了内存壁垒会强制缓存一致性吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读有关使用布尔值进行线程控制的问题并被@eran的这个答案所吸引:

仅在所有线程使用相同缓存的单核上使用volatile就足够了.在多核上,如果在一个内核上调用stop()而在另一内核上运行run(),则可能需要一些时间来使CPU缓存同步,这意味着两个内核可能会看到isRunning_的两个不同视图.

如果使用同步机制,它们将确保所有缓存获得相同的值,但代价是使程序停顿了一段时间.性能或正确性对您来说更重要取决于您的实际需求.

我花了一个多小时来搜索一些语句,该语句说同步原语强制高速缓存一致性,但是失败了.我最近到达的是维基百科:

关键字volatile不能保证强制执行高速缓存一致性的内存障碍.

这暗示了内存屏障确实可以提高缓存的一致性,并且由于某些同步原语是使用内存屏障来实现的(同样来自Wikipedia),因此这是一些证据".

但是我对确定是否相信这一点还不够了解,并确保我不会误解它.

有人可以澄清一下吗?

解决方案

据我了解,同步原语根本不会影响缓存的一致性. Cache 是法文,表示 hidden ,它对用户不可见.缓存一致性协议应该可以在程序员不参与的情况下工作.

同步原语将影响内存顺序,内存顺序定义明确,并且通过处理器的ISA对用户可见.

有关内存一致性和缓存一致性的入门摘自计算机体系结构综合讲座"合集.

编辑:为澄清您的疑问

Wikipedia的陈述是错误的.我认为混淆可能来自术语内存一致性缓存一致性.他们不是同一件事.

C中的volatile关键字表示始终从内存(而不是寄存器)中读取变量,并且编译器不会对其周围的加载/存储进行重新排序.这并不意味着硬件不会重新排序加载/存储.这是内存一致性问题.当使用较弱的一致性模型时,程序员需要使用同步原语来强制执行特定的排序.这与缓存一致性不同.例如,如果线程1修改了位置A,则在此事件后线程2加载了位置A,它将收到一个更新的(一致的)值.如果使用了高速缓存一致性,这应该会自动发生.内存排序是一个不同的问题.您可以查看著名的论文共享内存一致性模型:A教程以获取更多信息. Dekker算法是其中一个比较知名的示例,它需要顺序一致性或同步原语. /p>

EDIT2 :我想澄清一件事.虽然我的缓存一致性示例是正确的,但是在某些情况下,内存一致性似乎与之重叠.当在处理器中执行存储但延迟到高速缓存(它们在存储队列/缓冲区中)时,会出现这种情况.由于处理器的缓存尚未收到更新的值,因此其他缓存也不会.这可能看起来像是缓存一致性问题,但实际上并非如此,实际上它是ISA内存一致性模型的一部分.在这种情况下,可以使用同步原语将存储队列刷新到缓存.考虑到这一点,您以粗体突出显示的Wikipedia文本是正确的,但另一个仍然略有错误:关键字volatile不能保证强制执行高速缓存一致性的内存障碍.它应该说:关键字volatile不能保证强制执行内存一致性的内存障碍.

I was reading this question about using a bool for thread control and got intrigued by this answer by @eran:

Using volatile is enough only on single cores, where all threads use the same cache. On multi-cores, if stop() is called on one core and run() is executing on another, it might take some time for the CPU caches to synchronize, which means two cores might see two different views of isRunning_.

If you use synchronization mechanisms, they will ensure all caches get the same values, in the price of stalling the program for a while. Whether performance or correctness is more important to you depends on your actual needs.

I have spent over an hour searching for some statement that says synchronization primitives force cache coherency but have failed. The closest I have come is Wikipedia:

The keyword volatile does not guarantee a memory barrier to enforce cache-consistency.

Which suggests that memory barriers do force cache consistency, and since some synchronization primitives are implemented using memory barriers (again from Wikipedia) this is some "evidence".

But I don't know enough to be certain whether to believe this or not, and be sure that I'm not misinterpreting it.

Can someone please clarify this?

解决方案

As I understand, synchronization primitives won't affect cache coherency at all. Cache is French for hidden, it's not supposed to be visible to the user. A cache coherency protocol should work without the programmer's involvement.

Synchronization primitives will affect the memory ordering, which is well defined and visible to the user through the processor's ISA.

A good source with detailed information is A Primer on Memory Consistency and Cache Coherence from the Synthesis Lectures on Computer Architecture collection.

EDIT: To clarify your doubt

The Wikipedia statement is slightly wrong. I think the confusion might come from the terms memory consistency and cache coherency. They don't mean the same thing.

The volatile keyword in C means that the variable is always read from memory (as opposed to a register) and that the compiler won't reorder loads/stores around it. It doesn't mean the hardware won't reorder the loads/stores. This is a memory consistency problem. When using weaker consistency models the programmer is required to use synchronization primitives to enforce a specific ordering. This is not the same as cache coherency. For example, if thread 1 modifies location A, then after this event thread 2 loads location A, it will receive an updated (consistent) value. This should happen automatically if cache coherency is used. Memory ordering is a different problem. You can check out the famous paper Shared Memory Consistency Models: A Tutorial for more information. One of the better known examples is Dekker's Algorithm which requires sequential consistency or synchronization primitives.

EDIT2: I would like to clarify one thing. While my cache coherency example is correct, there is a situation where memory consistency might seem to overlap with it. This when stores are executed in the processor but delayed going to the cache (they are in a store queue/buffer). Since the processor's cache hasn't received an updated value, the other caches won't either. This may seem like a cache coherency problem but in reality it is not and is actually part of the memory consistency model of the ISA. In this case synchronization primitives can be used to flush the store queue to the cache. With this in mind, the Wikipedia text that you highlighted in bold is correct but this other one is still slightly wrong: The keyword volatile does not guarantee a memory barrier to enforce cache-consistency. It should say: The keyword volatile does not guarantee a memory barrier to enforce memory consistency.

这篇关于内存壁垒会强制缓存一致性吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆