【问题标题】:Can DMB instructions be safely omitted in ARM Cortex M4在 ARM Cortex M4 中可以安全地省略 DMB 指令吗
【发布时间】:2018-06-11 14:29:19
【问题描述】:

我正在查看由 GCC 为 ARM Cortex M4 生成的程序集,并注意到 atomic_compare_exchange_weak 在条件周围插入了两条 DMB 指令(使用 -std=gnu11 -O2 使用 GCC 4.9 编译):

// if (atomic_compare_exchange_weak(&address, &x, y))
dmb      sy
ldrex    r0, [r3]
cmp      r0, r2
itt      eq
strexeq  lr, r1, [r3]
cmpeq.w  lr, #0
dmb      sy
bne.n    ...

由于programming guide to barrier instructions for ARM Cortex M4 声明:

在图 41 和图 42 的示例中省略 DMB 或 DSB 指令不会导致任何错误,因为 Cortex-M 处理器:

  • 不要重新排序内存传输
  • 不允许两个写传输重叠。

在针对 Cortex M 时无法删除这些指令有什么原因吗?

【问题讨论】:

  • 您是否使用适当的-march 选项准确定位该处理器?
  • @JensGustedt 是的,一切都已设置并正常工作,该项目已有 1 年历史,我们只是改变了一些零件的工作方式,所以这是我第一次检查装配部分。

标签: c c11 cortex-m memory-barriers


【解决方案1】:

我不知道 Cortex M4 是否可以用于多 CPU/多核配置,但总的来说:

  1. 在单核系统中永远不需要内存屏障(可以始终省略)。
  2. 在多核系统中,在同一内存上运行的线程/进程可能在不同的内核上运行时,内存屏障始终是必需的(永远不能省略)。

在硬件级别是否存在重新排序的内存写入无关紧要。

当然,我希望 DMB 指令在不支持 SMP 的芯片上基本上是免费的,所以我不确定你为什么要尝试破解它。

请注意,基于问题引用编译器为原子内在函数生成的代码,我假设上下文是用于同步原子以使其符合高级规范,而不是其他用途,例如 MMIO 的 IO 屏障,并且上述“从不”不应被解读为适用于这种(不相关的)用途(尽管我怀疑,由于您已经引用的原因,它不适用于 Cortex M4)。

【讨论】:

  • 我认为在某些情况下单核系统需要内存屏障。例如,如果我们有一个带有内存映射寄存器的外设,并且我们希望在执行其他操作之前确保对该寄存器的写入完成(在总线上得到确认)。
  • @EugeneSh.:好吧,我应该澄清一下“从不”。我假设的上下文是原子同步以使它们符合高级规范,而不是其他用途,例如 MMIO 的 IO 屏障。
  • @R.. 谢谢,如果有人问我,我会回答自己,所以我只是想仔细检查一下。并不是说它有很大的不同,据我了解,每个 DMB 在 M4 上需要 1 个周期。
  • @R.. 顺便说一句,LPC4357 具有皮质 m4 和皮质 m0,共享相同的内存空间。
  • @R.. 不,有效类型的意图在 C 基本原理中得到了很好的解释。例如 int* 和 double* 可以别名不是本意。这开始被滥用的地方是 uint16_t* 之类的东西不能为 uint32_t* 等起别名,从而有效地使 gcc 的各种硬件相关编程特别成为安全隐患。结果,我们看到用 gcc 编写的嵌入式系统每天都在遭受破坏,因为普通的 C 程序员甚至不知道严格的别名和有效类型。自从 Cortex M 成为主流以来,情况就是如此。
猜你喜欢
  • 2019-12-14
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 2018-09-29
相关资源
最近更新 更多