保证内存排序和正确的编程实践

时间:2011-04-04 17:32:01

标签: c++ c++11 gcc intel amd-processor

关于我在下面描述的顺序,我有一些相关的问题。

  1. 鉴于这些排序保证,我在很多地方都不需要明确的围栏。但是,如何向编译器表达“栅栏”,特别是GCC?也就是说,只要优化器不对我的程序重新排序,程序顺序的保证才适用。

  2. 是否有普通/流行的新芯片使用通用核心而不提供此类保证?

  3. 我对C ++ 0x有点混淆与交错的想法。我必须使用“原子”类来使用这些保证,还是草案中还有其他一些方面也提供了一种利用这些保证的方法?


  4. 内存订购

    英特尔和AMD(至少使用x86_64)都保证内存加载与单个处理器上的存储操作相关。也就是说,如果某个处理器执行这些存储:

    1. 存储A< - 1
    2. 商店B < - 2
    3. 商店C < - 3
    4. 当其他处理器看到C(3)时,保证也可以看到先前的存储A(1)和B(2)。现在,处理器之间的可见性可能是交错的,但来自任何给定处理器的商店订单也将是顺序的。

      当处理器0读取处理器1存储的值时,它们也具有传递保证,然后写入一个值,读取新值的处理器2也必须从处理器1中看到该值。

      忽略处理IO和特殊设备的特殊情况。我只对一般的内存保证感兴趣:我在这里的排序只是我最感兴趣的一点,因为它对并发算法最重要。

3 个答案:

答案 0 :(得分:2)

掌握这些操作对于构建SMP操作系统和与某些类型的硬件进行通信至关重要。 Linux内核文档提供了该主题的完美概述以及内核使用的特定解决方案。我强烈建议您查看他们的memory-barriers.txt文件。

答案 1 :(得分:0)

为了最有力地保证您的商店和货物将以精确的顺序执行,您可能需要求助于代码中的asm块并写出您的{{1明确说明。

答案 2 :(得分:0)

即使平台保证了顺序一致性,当多个线程访问同一个内存位置时,总是需要某种同步来防止竞争条件其中一人写入其中。 C ++ 0x提供了三种实现此类同步的方法:

  1. 相互排斥 - std::mutex及相关课程
  2. 原子变量 - std::atomic<T>
  3. 明确的记忆障碍 - std::atomic_thread_fence
  4. 后两者接受内存顺序参数,允许在不保证顺序一致性的平台上具有额外的灵活性(仅限专家!),但这与x86无关。