首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++编译器如何支持C++11原子,而不支持C++11内存模型

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

Stack Overflow用户
提问于 2012-07-02 20:40:16
回答 3查看 5.9K关注 0票数 32

在查看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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-06 17:43:56

其中一个问题是“内存位置”的定义,它允许(并强制编译器支持)通过不同的锁来锁定不同的结构成员。有一个discussion about a RL problem caused by this

基本上,问题是像这样定义struct

代码语言:javascript
复制
struct x {
    long a;
    unsigned int b1;
    unsigned int b2:1;
};

编译器也可以通过重写b2实现对b1的自由写入(显然,从报告中可以看出,它确实是这样做的)。因此,必须将这两个字段锁定为一个字段。然而,由于C++11内存模型的原因,这是被禁止的(好吧,并不是真的被禁止,但是编译器必须确保对b1b2的同时更新不会干扰;它可以通过锁定或对每个这样的更新执行C++11来做到这一点,嗯,在某些体系结构上很难做到这一点)。引用报告中的话:

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

更好的信息也可以在wiki中找到。

票数 15
EN

Stack Overflow用户

发布于 2012-07-04 01:12:00

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

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

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

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

代码语言:javascript
复制
for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++count;
}

可以优化为:

代码语言:javascript
复制
register int r1 = count;
for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++r1;
}
count = r1;

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

详情请参见Concurrency memory model compiler consequences

票数 11
EN

Stack Overflow用户

发布于 2012-07-03 02:55:16

这并不是说它们不支持内存模型,而是它们(还)不支持标准中用于与内存模型交互的API。该API包括许多互斥锁。

然而,Clang和GCC在没有正式标准的情况下尽可能地了解线程已经有一段时间了。您不必担心优化会将事物移到原子操作的错误一侧。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11293885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档