简体   繁体   English

为什么内存屏障不只阻止每个特定内存地址的指令?

[英]Why don't memory barriers only block instructions per specific memory address?

As I understand it, a memory barrier will "separate" loads/stores (depending on what type of barrier is used) regardless of the memory address associated with the "fenced" instruction.据我了解,无论与“围栏”指令关联的内存地址如何,内存屏障都会“分离”加载/存储(取决于使用的屏障类型)。 So if we had an atomic increment, surrounded by loads and stores:所以如果我们有一个原子增量,被加载和存储包围:

LOAD A
STORE B
LOAD C
LOCK ADD D    ; Assume full fence here
LOAD E
STORE F

the instructions operating on A, B and C would have to complete before D;操作 A、B 和 C 的指令必须在 D 之前完成; and E and F may not start until after D. E 和 F 可能在 D 之后才开始。

However, as the LOCK is only applied to address D, why restrict the other instructions?但是,既然LOCK只作用于地址D,为什么要限制其他指令呢? Is it too complicated to implement in circuitry?在电路中实现是否太复杂? Or is there another reason?还是另有原因?

The basic reason is because the basic intent of a fence is to enforce ordering, so if the fence affected only reads/writes of the specific item to which it was applied, it wouldn't do its job.基本原因是因为围栏的基本意图是强制执行顺序,所以如果围栏只影响对其应用的特定项目的读/写,它就不会完成它的工作。

For example, you fairly frequently have patterns like:例如,你经常有这样的模式:

prepare some data
signal that the data is ready

and:和:

consume some data
signal that the memory used for the data is now free

In such cases, the memory location used as the "signal" is what you're probably going to protect with the fence--but it's not the only thing that really needs to be protected.在这种情况下,用作“信号”的内存位置是您可能要用围栏保护的东西——但这并不是真正需要保护的唯一东西。

In the first case, I have to assure that all the code that writes the data gets executed, and only after it's all done, the signal will be set.在第一种情况下,我必须确保所有写入数据的代码都得到执行,并且只有在全部完成后,才会设置信号。

Another thread can then see that the signal is set.然后另一个线程可以看到信号已设置。 Based on that, it knows that it can read all the data associated with the signal, not just the signal itself.基于此,它知道它可以读取与信号相关的所有数据,而不仅仅是信号本身。 If the fence affected only the signal itself, it would mean that the other code that was writing the data might still execute after the signal--and then we'd get a collision between that code writing the data, and the other code trying to read the data.如果栅栏仅影响信号本身,则意味着写入数据的其他代码可能仍会在该信号之后执行——然后我们会在写入数据的代码与试图执行数据的其他代码之间发生冲突读取数据。

In theory, we could get around that by using a fence around each individual piece of data being written.理论上,我们可以通过在正在写入的每个单独数据块周围使用围栏来解决这个问题。 In reality, we almost certainly want to avoid that--a fence is fairly expensive, so we'd usually prefer to write a significant amount of data, then use a single fence to indicate that the entire "chunk" of memory is ready.实际上,我们几乎肯定要避免这种情况——栅栏相当昂贵,因此我们通常更愿意写入大量数据,然后使用单个栅栏来指示整个“块”内存已准备就绪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM