我可以在多核x86 CPU上强制缓存一致性吗? [英] Can I force cache coherency on a multicore x86 CPU?

查看:308
本文介绍了我可以在多核x86 CPU上强制缓存一致性吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

另一周,我写了一个小线程类和一个单向消息管道,以允许线程之间的通信(每个线程两个管道,显然,对于双向通信)。一切都在我的Athlon 64 X2上正常工作,但是我想知道如果两个线程都在查看同一个变量并且每个核心上该变量的本地缓存值不同步,我是否会遇到任何问题。

The other week, I wrote a little thread class and a one-way message pipe to allow communication between threads (two pipes per thread, obviously, for bidirectional communication). Everything worked fine on my Athlon 64 X2, but I was wondering if I'd run into any problems if both threads were looking at the same variable and the local cached value for this variable on each core was out of sync.

我知道 volatile 关键字将强制一个变量从内存刷新,但是有一种方式在多核x86处理器强制所有核心的缓存同步?这是我需要担心的,或将会易失性和正确使用轻量级锁定机制(我使用_InterlockedExchange设置我的挥发性管道变量)处理所有情况下,我想写锁定自由多核x86 CPU的代码?

I know the volatile keyword will force a variable to refresh from memory, but is there a way on multicore x86 processors to force the caches of all cores to synchronize? Is this something I need to worry about, or will volatile and proper use of lightweight locking mechanisms (I was using _InterlockedExchange to set my volatile pipe variables) handle all cases where I want to write "lock free" code for multicore x86 CPUs?

我已经知道并使用了Critical Sections,Mutexes,Events等。我主要想知道是否有x86内在函数,我不知道哪个力或可以用于强制缓存一致性。

I'm already aware of and have used Critical Sections, Mutexes, Events, and so on. I'm mostly wondering if there are x86 intrinsics that I'm not aware of which force or can be used to enforce cache coherency.

推荐答案

volatile 只会强制您的代码重新读取值,因此无法控制从哪里读取值。如果该值最近被您的代码读取,那么它可能在缓存中,在这种情况下,volatile将强制它从缓存中重新读取,而不是从内存中读取。

volatile only forces your code to re-read the value, it cannot control where the value is read from. If the value was recently read by your code then it will probably be in cache, in which case volatile will force it to be re-read from cache, NOT from memory.

在x86中没有很多缓存一致性指令。有预取指令,如 prefetchnta ,但不影响内存排序语义。它通过将值带入L1缓存而不污染L2,但是对于具有大的共享包含 L3缓存的现代英特尔设计,情况更复杂。

There are not a lot of cache coherency instructions in x86. There are prefetch instructions like prefetchnta, but that doesn't affect the memory-ordering semantics. It used to be implemented by bringing the value to L1 cache without polluting L2, but things are more complicated for modern Intel designs with a large shared inclusive L3 cache.

x86 CPU使用 MESI协议(MESIF for Intel,MOESI for AMD)保持它们的缓存彼此一致(包括不同核的私有L1高速缓存)。要写入缓存行的核心必须强制其他核心使其副本无效,然后才能将其自己的副本从共享更改为修改状态。

x86 CPUs use a variation on the MESI protocol (MESIF for Intel, MOESI for AMD) to keep their caches coherent with each other (including the private L1 caches of different cores). A core that wants to write a cache line has to force other cores to invalidate their copy of it before it can change its own copy from Shared to Modified state.

你不需要任何围栏指令(例如MFENCE)在一个线程中产生数据,而在x86中使用另一个线程,因为x86加载/存储具有内置的获取/释放语义。你需要MFENCE(全屏障)来获得顺序一致性。 (此回答的先前版本建议需要 clflush ,这是不正确的)。

You don't need any fence instructions (like MFENCE) to produce data in one thread and consume it in another on x86, because x86 loads/stores have acquire/release semantics built-in. You do need MFENCE (full barrier) to get sequential consistency. (A previous version of this answer suggested that clflush was needed, which is incorrect).

阻止编译时重新排序,因为C ++的内存模型是弱排序的。 volatile 是一个旧的,糟糕的方法来做到这一点; C ++ 11 std :: atomic是一个更好的方式来编写无锁代码。

You do need to prevent compile-time reordering, because C++'s memory model is weakly-ordered. volatile is an old, bad way to do this; C++11 std::atomic is a much better way to write lock-free code.

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

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