单核ARM上的存储器屏障

单核ARM上的存储器屏障,arm,memory-barriers,Arm,Memory Barriers,有很多信息与记忆障碍有关。大多数信息涉及多核或多处理器体系结构。Stackoverflow中的某个地方还指出,单核处理器上不需要内存屏障 到目前为止,我找不到任何明确的解释,为什么单核CPU不需要它。假设加载和存储在线程a中重新排序,并且两条指令之间发生上下文切换。在这种情况下,线程B的反应可能不符合预期。为什么单核上的上下文切换与不同核上的两个线程的行为不同?(缓存一致性问题除外) 例如,ARM网站上的一些信息: “根据架构定义,软件必须执行数据内存屏障(DMB)操作: •例如,通过锁定互斥锁

有很多信息与记忆障碍有关。大多数信息涉及多核或多处理器体系结构。Stackoverflow中的某个地方还指出,单核处理器上不需要内存屏障

到目前为止,我找不到任何明确的解释,为什么单核CPU不需要它。假设加载和存储在线程a中重新排序,并且两条指令之间发生上下文切换。在这种情况下,线程B的反应可能不符合预期。为什么单核上的上下文切换与不同核上的两个线程的行为不同?(缓存一致性问题除外)

例如,ARM网站上的一些信息:

“根据架构定义,软件必须执行数据内存屏障(DMB)操作: •例如,通过锁定互斥锁(互斥)或减少信号量来获取资源,以及对该资源进行任何访问 •在使资源可用之前,例如,通过解锁互斥锁或增加信号量”

这听起来很清楚,但是在提供的示例中,它们明确地提到了多核配置

为什么单核上的上下文切换与不同核上的两个线程的行为不同?(缓存一致性问题除外)

单独磁芯上的线程可能在完全相同的时间起作用。在单个核心上仍然存在问题


Stackoverflow中的某个地方还指出,单核处理器上不需要内存屏障

这些信息可能是断章取义的(或者没有提供足够的上下文)


页面的执行顺序与编译器重新排序优化和编译时/运行时排序不同。在管道中有许多地方,内存的顺序可能很重要。在某些情况下,这可能由编译器、操作系统或我们自己的代码来处理

编译器内存障碍适用于单个CPU。它们特别适用于写和读的顺序和定时很重要的硬件

Linux定义了更多

  • 写入/存储
  • 数据依赖性
  • 读取/加载
  • 一般记忆障碍
  • 主要是这些映射到
    DMB
    DSB
    IMB
    更多用于代码修改)

    ARM CPU越先进,就有多个加载/存储单元。理论上,一些非抢占式线程开关注1(特别是使用别名内存)可能会导致多线程单CPU应用程序出现一些问题。然而,构建这个案例是相当困难的

    在大多数情况下,良好的内存排序是由CPU通过调度指令来处理的。对于系统级程序员来说,改变
    CP15
    寄存器是一种常见的情况,在这种情况下,单CPU的性能确实很重要。例如,打开MMU时应发出
    ISB
    。对于某些硬件/设备寄存器也是如此。最后,即使在单CPU系统上,程序加载器也需要屏障和缓存操作

    写了这些关于内存访问顺序的博客

    这个话题很复杂,你必须明确你所讨论的障碍类型


    注1:我说的是非抢占性,就像发生中断一样,单个CPU可能会确保所有未完成的内存请求都已完成。使用非抢占式开关,您可以执行类似于
    longjmp
    的操作来更改线程。理论上,你可以在所有写作完成之前改变上下文。系统只需要在
    yield()
    中使用
    DMB
    来避免这种情况。

    CPU只会对已经“发出”的指令重新排序,因此上下文切换不会停止已经在管道中的任何指令,它们将继续执行,直到完成

    在上下文切换完成时,这些指令中的任何一条都不太可能完成。上下文开关通常保存所有寄存器的状态,从而对修改寄存器以首先完成的每条指令产生依赖性

    然而,即使对于重新排序的指令仍然通过上下文开关(可能是内存存储)执行的不太可能的情况,CPU也会确保它向软件显示指令以正确的顺序执行。因此,当第二个线程尝试访问共享数据时,CPU将确保在允许相关指令执行之前,已完成必要的指令


    多核情况实际上是保持对缓存/内存的写入顺序,以便其他核看到以正确顺序发生的更改。只有这样才需要内存屏障。

    但假设优化已关闭,并且编译器没有对don进行重新排序。所以当我们只讨论cpu的重新排序时,对于单个cpu来说,它几乎100%是不可见的。我对一些不需要的情况进行了编辑。“Stackoverflow中的某个地方还指出,单核处理器上不需要内存屏障。”体系结构有不同的内存排序方法,如强弱排序。因此,这句话可能适用于前一句。是的,寄存器也是如此,但寄存器可能存储/挂起到许多位置。如果缓存内容并对两个具有不同内存空间的进程使用别名,则情况并非如此。我认为在任何调度器上下文切换中设置内存障碍是明智的。也许有可能使这成为不必要的。但是,我不认为您可以说它在所有情况下都是不需要的(内存空间会破坏缓存逻辑)?当然,这可能是非常罕见的,在某些系统中可能不可能。”然而,即使是在不太可能的情况下,重新订购指令