简体   繁体   English

内存栅栏和内存栅栏一样吗?

[英]Is memory fence and memory barrier same?

here I am confused with the term memory fence (fence function in rust).在这里,我与术语记忆栅栏(铁锈中的栅栏功能)混淆了。 I can clearly understand what is memory barrier in terms of atomics but I was unable to figure out what is memory fence.我可以清楚地理解原子方面的内存屏障是什么,但我无法弄清楚什么是内存屏障。

Are memory fence and memory barriers the same?内存栅栏和内存屏障是一样的吗? if not what is the difference and when to use memory fence over memory barrier?如果不是,有什么区别以及何时在内存屏障上使用内存栅栏?

There is no difference.没有区别。

"Fence" and "barrier" mean the same thing in this context.在这种情况下,“围栏”和“屏障”是同一个意思。

A "fence" in this context is a kind of memory barrier.在这种情况下,“栅栏”是一种内存屏障。 This distinction is important.这种区别很重要。 For the purposes of this discussion I'll distinguish informally between three kinds of beasts:出于本次讨论的目的,我将非正式地区分三种野兽:

  • Atomic fence: controls the order in which observers can see the effects of atomic memory operations.原子栅栏:控制观察者可以看到原子内存操作效果的顺序。 (This is what you asked about.) (这就是你问的。)
  • More general memory barrier: controls the order of actual operations against memory or memory-mapped I/O.更通用的内存屏障:控制针对内存或内存映射 I/O 的实际操作顺序。 This is often a bigger hammer that can achieve similar results to an atomic fence, but at higher cost.这通常是一个更大的锤子,可以达到与原子栅栏相似的效果,但成本更高。 (Depends on the architecture.) (取决于架构。)
  • Compiler fence: controls the order of instructions the processor receives.编译器栅栏:控制处理器接收指令的顺序 This is not what you asked about, but people often accidentally use this in place of a real barrier, which makes them sad later.这不是你问的,但人们经常不小心用它来代替真正的障碍,这让他们以后很难过。

What fence is什么是栅栏

Rust's std::sync::atomic::fence provides an atomic fence operation, which provides synchronization between other atomic fences and atomic memory operations. Rust 的std::sync::atomic::fence提供了一个原子栅栏操作,它提供了其他原子栅栏和原子内存操作之间的同步。 The terms folks use for describing the various atomic conditions can be a little daunting at first, but they are pretty well defined in the docs, though at the time of this writing there are some omissions.人们用来描述各种原子条件的术语起初可能有点令人生畏,但它们在文档中得到了很好的定义,尽管在撰写本文时有一些遗漏。 Here are the docs I suggest reading if you want to learn more.如果您想了解更多信息,我建议您阅读以下文档。

First, Rust's docs for the Ordering type .首先, Rust 的Ordering类型文档 This is a pretty good description of how operations with different Ordering interact, with less jargon than a lot of references in this area (atomic memory orderings).这是对具有不同Ordering操作如何交互的一个很好的描述,比这方面的大量参考(原子内存排序)用更少的术语。 However, at the time of this writing, it's misleading for your specific question, because it says things like但是,在撰写本文时,它对您的具体问题具有误导性,因为它说的是

This ordering is only applicable for operations that can perform a store.此排序仅适用于可以执行存储的操作。

which ignores the existence of fence .忽略了fence的存在。

The docs for fence go a little ways to repair that. fence文档提供了一些修复方法。 IMO the docs in this area could use some love. IMO 在这方面的文档可以使用一些爱。

However, if you want all the interactions precisely laid out, I'm afraid you must look to a different source: the equivalent C++ docs .但是,如果您想要精确地布置所有交互,恐怕您必须寻找不同的来源:等效的 C++ docs I know, we're not writing C++, but Rust inherits a lot of this behavior from LLVM, and LLVM tries to follow the C++ standard here.我知道,我们不是在编写 C++,但是 Rust 从 LLVM 继承了很多这种行为,并且 LLVM 在这里尝试遵循 C++ 标准。 The C++ docs are much higher in jargon, but if you read slowly it's not actually more complex than the Rust docs -- just jargony. C++ 文档的行话高得多,但如果你慢慢阅读,它实际上并不比 Rust 文档更复杂——只是行话。 The nice thing about the C++ docs is that they discuss each interaction case between load/store/fence and load/store/fence. C++ 文档的好处在于它们讨论了加载/存储/围栏和加载/存储/围栏之间的每个交互案例。

What fence is not什么栅栏不是

The most common place that I employ memory barriers is to reason about completion of writes to memory-mapped I/O in low level code, such as drivers.我使用内存屏障的最常见的地方是推理在低级代码(例如驱动程序)中对内存映射 I/O 的写入完成。 (This is because I tend to work low in the stack, so this may not apply to your case.) In this case, you are likely performing volatile memory accesses, and you want barriers that are stronger than what fence offers. (这是因为我倾向于在堆栈中工作,所以这可能不适用于您的情况。)在这种情况下,您可能正在执行volatile内存访问,并且您需要比fence提供的屏障更强的屏障。

In particular, fence helps you reason about which atomic memory operations are visible to which other atomic memory operations -- it does not help you reason about whether a particular stored value has made it all the way through the memory hierarchy and onto a particular level of the bus.特别是, fence可以帮助您推理哪些原子内存操作对哪些其他原子内存操作可见——它不能帮助您推理某个特定存储值是否已经通过内存层次结构一直到达特定级别公交车。 For instance.例如。 For cases like that, you need a different sort of memory barrier.对于这种情况,您需要一种不同类型的内存屏障。

These are the sorts of barriers described in considerable detail in the Linux Kernel's documentation on memory barriers .这些是Linux 内核关于内存屏障的文档中相当详细地描述的各种屏障

In response to another answer on this question that flat stated that fence and barrier are equivalent, I raised this case on the Rust Unsafe Code Guidelines issue tracker and got some clarifications.为了回应关于这个问题的另一个答案,flat 声明栅栏和屏障是等效的,我 在 Rust 不安全代码指南问题跟踪器上提出了这个案例,并得到了一些澄清。

In particular, you might notice that the docs for Ordering and fence make no mention of how they interact with volatile memory accesses, and that's because they do not.特别是,您可能会注意到Orderingfence的文档没有提到它们如何与volatile内存访问交互,那是因为它们没有。 Or at least, they aren't guaranteed to -- on certain architectures the instructions that need to be generated are the same (ARM), and in other cases, they are not (PowerPC).或者至少,它们不能保证——在某些架构上,需要生成的指令是相同的 (ARM),而在其他情况下,它们不是 (PowerPC)。

Rust currently provides a portable atomic fence (which you found), but does not provide portable versions of any other sort of memory barrier, like those provided in the Linux kernel. Rust 目前提供了一个可移植的原子栅栏(你已经​​找到了),但不提供任何其他类型的内存屏障的可移植版本,如 Linux 内核中提供的那些。 If you need to reason about the completion of (for example) volatile memory accesses, you will need either non-portable asm!如果您需要推理(例如) volatile内存访问的完成,您将需要非便携式asm! or a function/macro that winds up producing it.或最终生成它的函数/宏。

Aside: compiler fences旁白:编译器围栏

When I make statements like what I said above, someone inevitably hops in with (GCC syntax)当我做出像上面所说的那样的陈述时,不可避免地会有人加入(GCC 语法)

asm("" :::: memory);

This is neither an atomic fence nor a memory barrier: it is roughly equivalent to Rust's compiler_fence , in that it discourages the compiler from reordering memory accesses across that point in the generated code.这既不是原子栅栏也不是内存屏障:它大致相当于 Rust 的compiler_fence ,因为它阻止编译器在生成的代码中跨该点重新排序内存访问。 It has no effect on the order that the instructions are started or finished by the machine.对机器启动或完成指令的顺序没有影响。

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

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