繁体   English   中英

C ++编译器如何支持C ++ 11原子,但不支持C ++ 11内存模型

[英]How can C++ compilers support C++11 atomic, but not support C++11 memory model

在查看Clang和g ++ C ++ 11实现状态时,我注意到一些奇怪的事情:
它们支持C ++ 11原子,但它们不支持C ++ 11内存模型。
我的印象是你必须有C ++ 11内存模型才能使用原子。 那么对原子和内存模型的支持究竟有什么区别呢?
缺乏内存模型支持意味着使用std::atomic<T>合法C ++ 11程序是不是一致的?

引用:
http://clang.llvm.org/cxx_status.html
http://gcc.gnu.org/gcc-4.7/cxx0x_status.html

其中一个问题是“内存位置”的定义,它允许(并强制编译器支持)通过不同的锁来锁定不同的结构成员。 讨论由此引起的RL问题

基本上问题是有一个像这样定义的struct

struct x {
    long a;
    unsigned int b1;
    unsigned int b2:1;
};

编译器也可以通过覆盖b1来实现对b2的写入(显然,从报告来看,它确实如此)。 因此,必须将两个字段锁定为一个字段。 但是,作为C ++ 11内存模型的结果,这是禁止的(好吧,不是真的被禁止,但编译器必须确保对b1b2同时更新不会干扰;它可以通过锁定或CAS-ing来实现这样的更新,在一些架构上生活很困难)。 引用报告:

我向我们的GCC人员提出了这个问题,他们告诉我:“C不提供这样的保证,如果他们共享自然对齐的字大小的内存区域,也不能用不同的锁定可靠地锁定不同的结构字段.C + +11内存模型可以保证这一点,但是没有实现,也没有使用C ++ 11编译器构建内核。“

wiki中也可以找到不错的信息。

我想在这些情况下“缺乏内存模型”只意味着优化器是在C ++ 11内存模型发布之前编写的,并且可能现在执行无效的优化。 验证针对内存模型的优化是非常困难和耗时的,因此clang / gcc团队还没有完成这一点也就不足为奇了。

缺乏内存模型支持是否意味着使用std :: atomic的合法C ++ 11程序不是seq一致的?

是的,这是可能的。 更糟糕的是:编译器可能会引入数据竞争(根据C ++ 11标准)无竞争程序,例如通过引入推测性写入。

例如,用于执行此优化的几个C ++编译器:

for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++count;
}

可以优化到:

register int r1 = count;
for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++r1;
}
count = r1;

如果所有p->data都是非负数,则原始源代码不会写入count ,但优化后的代码会执行。 这可以在一个无竞争的程序中引入数据竞争,因此C ++ 11规范不允许这样的优化。 现有的编译器现在必须验证(并在必要时进行调整)所有优化。

有关详细信息,请参阅并发内存模型编译器结

它不是支持内存模型,而是它们(还)支持标准中的API以与内存模型交互。 该API包含许多互斥锁。

但是,Clang和GCC在一段时间内没有正式标准就已尽可能地了解线程。 您不必担心优化将事物移到原子操作的错误一边。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM