为什么 std::atomic<bool> 比 volatile bool 慢得多?

新手上路,请多包涵

多年来,我一直在使用 volatile bool 进行线程执行控制,效果很好

// in my class declaration
volatile bool stop_;

-----------------

// In the thread function
while (!stop_)
{
     do_things();
}

现在,由于 C++11 增加了对原子操作的支持,我决定尝试一下

// in my class declaration
std::atomic<bool> stop_;

-----------------

// In the thread function
while (!stop_)
{
     do_things();
}

但它比 volatile bool 慢了几个数量级!

我编写的简单测试用例使用 volatile bool 方法大约需要 1 秒才能完成。使用 std::atomic<bool> 但是我已经等了大约 10 分钟然后放弃了!

我尝试使用 memory_order_relaxed 标志与 loadstore 达到相同的效果。

我的平台:

  • Windows 7 64 位
  • MinGW gcc 4.6.x

我做错了什么?

注意:我知道 volatile 不会使变量成为线程安全的。我的问题不是关于 volatile,而是关于为什么 atomic 慢得离谱。

原文由 user1773602 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 892
2 个回答

来自“Olaf Dietsche”的代码

 USE ATOMIC
 real   0m1.958s
 user   0m1.957s
 sys    0m0.000s

 USE VOLATILE
 real   0m1.966s
 user   0m1.953s
 sys    0m0.010s

如果您使用的是 GCC SMALLER 4.7

http://gcc.gnu.org/gcc-4.7/changes.html

添加了对指定 C++11/C11 内存模型的原子操作的支持。这些新的 __atomic 例程替换了现有的 __sync 内置例程。

原子支持也可用于内存块。如果内存块的大小和对齐方式与支持的整数类型相同,则将使用无锁指令。没有无锁支持的原子操作被保留为函数调用。 GCC atomic wiki 的“External Atomics Library”部分提供了一组库函数。

所以是的..唯一的解决方案是升级到 GCC 4.7

原文由 KoKuToru 发布,翻译遵循 CC BY-SA 3.0 许可协议

由于对此感到好奇,我自己在 Ubuntu 12.04、AMD 2.3 GHz、gcc 4.6.3 上对其进行了测试。

 #if 1
#include <atomic>
std::atomic<bool> stop_(false);
#else
volatile bool stop_ = false;
#endif

int main(int argc, char **argv)
{
    long n = 1000000000;
    while (!stop_) {
        if (--n < 0)
            stop_ = true;
    }

    return 0;
}

编译为 g++ -g -std=c++0x -O3 a.cpp

虽然,与@aleguna 的结论相同:

  • 只是 bool

实际0m0.004s

用户 0m0.000s

系统 0m0.004s

  • volatile bool

$时间./a.out

真实0m1.413s

用户 0m1.368s

系统 0m0.008s

  • std::atomic<bool> :

$时间./a.out

真正的 0m32.550s

用户 0m32.466s

系统 0m0.008s

  • std::atomic<int>

$时间./a.out

真正的 0m32.091s

用户 0m31.958s

系统 0m0.012s


2022 年 4 月 10 日更新,AMD 锐龙 3 3200G,g++ 9.3.0:

看起来 atomic 与 volatile 相比有了很大的改进。我将循环计数器增加到 10,000,000,000,以获得更精确的画面。虽然幅度不会因此次调整而改变:

  • std::atomic<bool> , std::atomic<int> : ~2.9s
  • volatile bool : ~5.4s

原文由 Olaf Dietsche 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题