有很多关于内存屏障的信息。大多数信息是指多核或多处理器架构。 Stackoverflow 上的某个地方还指出,单核处理器不需要内存屏障。
到目前为止,我找不到任何明确的解释,为什么单核 CPU 上不需要它。假设加载和存储在线程 A 中重新排序,并且在两条指令之间发生上下文切换。在这种情况下,线程 B 可能不会按预期使用react。与不同内核上的 2 个线程相比,为什么单个内核上的上下文切换行为会有所不同? (除了任何缓存一致性问题)
例如来自 ARM 网站的一些信息:
“在架构上定义软件必须执行数据内存屏障 (DMB) 操作:
• 在获取资源(例如,通过锁定互斥体(互斥)或递减信号量)与对该资源进行任何访问之间
• 在使资源可用之前,例如,通过解锁互斥锁或增加信号量”
这听起来很清楚,但是在提供的示例中,它们明确地指的是多核配置。
最佳答案
Why would a context switch on a single core behave differently compared to 2 threads on different cores ? (except any cache coherency issues)
单独核心上的线程可能在 处起作用正好同时。您在单核上仍然有问题。
Somewhere here on Stackoverflow is also stated that memory barriers are not required on single core processors.
此信息可能脱离上下文(或未提供足够的上下文)。
Wikipedia's Memory barrier和 Memory ordering页面包含乱序执行与编译器重新排序优化和编译时/运行时排序部分。管道中有很多地方内存的顺序可能很重要。在某些情况下,这可能由编译器、操作系统或我们自己的代码来处理。
编译器内存屏障适用于单个 CPU。它们对于写入和读取的顺序和时间很重要的硬件特别有用。
Linux 定义了更多 types of memory barriers ,
主要是这些映射到
DMB
( DSB
和 IMB
更多用于代码修改)。更先进的 ARM CPU 具有多个加载/存储单元。理论上一些非抢占式线程切换注1 (尤其是使用别名内存)可能会导致多线程单 CPU 应用程序出现一些问题。然而,构建这个案例将是相当困难的。
在大多数情况下,良好的内存排序是由 CPU 通过调度指令处理的。对于单个 CPU 来说很重要的一个常见情况是系统级程序员更改
CP15
寄存器。例如,一个 ISB
打开 MMU 时应发出。对于某些硬件/设备寄存器可能也是如此。最后,即使在单 CPU 系统上,程序加载器也需要屏障和缓存操作。UnixSmurf写了这些关于内存访问顺序的博客,
这个话题很复杂,你必须具体说明你正在讨论的障碍类型。
注1:我说非抢占式就好像发生了中断一样,单个 CPU 可能会确保所有未完成的内存请求都已完成。使用非抢占式交换机,您可以执行类似
longjmp
的操作改变线程。理论上,您可以在所有写入完成之前更改上下文。系统只需要一个 DMB
在 yield()
避免它。
关于arm - 单核 ARM 上的内存屏障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28285943/