31

我了解 DSB、DMB 和 ISB 是防止指令重新排序的障碍。我也可以为它们中的每一个找到很多非常好的解释,但是很难想象我必须使用它们的情况。

另外,从开源代码中,我不时看到这些障碍,但很难理解为什么要使用它们。举个例子,在Linux kernel 3.7 tcp_rcv_synsent_state_process函数中,有如下一行:

    if (unlikely(po->origdev))
            sll->sll_ifindex = orig_dev->ifindex;
    else
            sll->sll_ifindex = dev->ifindex;

    smp_mb();

    if (po->tp_version <= TPACKET_V2)
            __packet_set_status(po, h.raw, status);

其中 smp_mb() 基本上是 DMB。你能给我一些你在现实生活中的例子吗?这将有助于更多地了解障碍。

4

3 回答 3

47

抱歉,不会像你问的那样给你一个直截了当的例子,因为你已经在查看 Linux 源代码,你有很多可以去的地方,而且它们似乎没有帮助。没有什么可耻的——每个理智的人至少最初都会被内存访问顺序问题弄糊涂:)

如果您主要是应用程序开发人员,那么您很有可能无需过多担心 - 您使用的任何并发框架都会为您解决它。

如果您主要是设备驱动程序开发人员,那么示例很容易找到 - 只要您的代码中存在对先前访问的依赖关系,该访问在执行其他一些访问之前已经产生了影响(清除了中断源,写入了 DMA 描述符) (重新启用中断,启动 DMA 事务)。

如果您正在开发一个并发框架(或调试一个),您可能需要更多地阅读该主题 - 但您的问题表明一种肤浅的好奇心,而不是迫切的需要?如果您正在开发自己的在线程之间传递数据的方法,而不是基于并发框架提供的原语,那么这就是并发框架的所有意图和目的。

Paul McKenney 写了一篇关于内存屏障的必要性以及它们对处理器的实际影响的优秀论文:内存屏障:软件黑客的硬件视图

如果这有点太硬核,我写了一个由 3 部分组成的博客系列,它更轻量级,并以特定于 ARM 的视图结束。第一部分是内存访问排序 - 介绍

但是,如果它是您所追求的具体示例列表,特别是对于 ARM 架构,您可能会比Barrier Litmus Tests 和 Cookbook做得更糟。

超轻程序员的观点和不完全架构正确的版本是:

  • DMB - 每当内存访问需要对另一个内存访问进行排序时。
  • DSB - 每当需要在程序执行之前完成内存访问时。
  • ISB - 每当指令提取需要在程序中的某个点之后显式发生时,例如在内存映射更新之后或在编写要执行的代码之后。(实际上,这意味着“此时丢弃任何预取指令”。)
于 2013-03-19T07:39:43.623 回答
9

通常,在您必须确保内存访问以特定顺序发生的情况下,您需要使用内存屏障。这可能出于多种原因需要,通常当两个或多个进程/线程或硬件组件访问必须保持一致的相同内存结构时需要它。

它在 DMA 传输中经常使用。一个简单的 DMA 控制结构可能如下所示:

struct dma_control {
  u32 owner;
  void * data;
  u32 len;
};

所有者通常会设置为类似 OWNER_CPU 或 OWNER_HARDWARE,以指示允许两个参与者中的谁使用该结构。

改变它的代码通常会像这样

dma->data = data;
dma->len  = length;
smp_mb();
dma->owner = OWNER_HARDWARE;

因此,数据 len 总是在所有权转移到 DMA 硬件之前设置。否则引擎可能会得到陈旧的数据,例如未更新的指针或长度,因为 CPU 重新排序了内存访问。

对于在不同内核上运行的进程或线程也是如此。可以以类似的方式进行通信。

于 2013-03-19T07:26:06.190 回答
3

屏障要求的一个简单示例是自旋锁。如果您使用比较和交换(或 ARM 上的 LDREX/STREX)实现自旋锁并且没有障碍,则允许处理器推测性地从内存中加载值并将计算值延迟存储到内存中,并且这些都不需要发生按照指令流中的加载/存储顺序。

DMB 尤其可以防止内存访问围绕 DMB 重新排序。如果没有 DMB,处理器可以在自旋锁释放后重新排序存储到受自旋锁保护的内存。或者,处理器可以在自旋锁实际锁定之前或在它被不同的上下文锁定时读取受自旋锁保护的内存。

unixsmurf 已经指出了这一点,但我也会向您指出Barrier Litmus Tests 和 Cookbook。它有一些很好的例子来说明你应该在哪里以及为什么应该使用障碍。

于 2013-07-31T06:31:16.713 回答