c++ - c++ 11 atomic是否自动解决变量读写上的多核竞争?

标签 c++ multithreading c++11 atomic core

我知道当多个线程读取和写入变量时,atomic 将对类型“T”变量应用锁,确保只有其中一个线程在执行 R/W。

但是在多核计算机中,线程可以运行在不同的核上,不同的核会有不同的一级缓存,二级缓存,同时共享三级缓存。我们知道有时 C++ 编译器会优化一个变量以存储在寄存器中,这样如果一个变量没有存储在内存中,那么变量上的不同核心缓存之间就没有内存同步。

所以我的担心/问题是,如果一个原子变量被编译器优化为某个寄存器变量,那么它就不会存储在内存中,当一个核心写入它的值时,另一个核心可能会读出一个陈旧的值,对吧?这个数据一致性有什么保证吗?

谢谢。

最佳答案

Atomic 不会按照您模糊描述的方式“解决”问题。它为基于顺序的内存一致性提供了某些非常具体的保证。

各种编译器在不同平台上以不同方式实现这些保证。

在 x86/64 上,没有锁用于原子整数和达到合理大小的指针。并且硬件提供了比标准要求更强的保证,使得一些更深奥的选项等同于完全一致。

我无法完全回答您的问题,但我可以为您指明正确的方向;您需要了解的主题是“C++ 内存模型”。

也就是说,存在原子是为了避免您描述的确切问题。如果您要求完全的内存顺序一致性,并且线程 A 修改 X,然后修改 Y,则没有其他线程可以看到 Y 被修改但 X 看不到。C++ 标准没有指定如何提供这种保证;缓存行失效、使用特殊指令进行访问、禁止编译器进行某些基于寄存器的优化等都是编译器要做的事情。

请注意,C++ 内存模型针对 C++17 进行了改进、错误修复和优化,以描述新的并行算法的行为并允许它们在具有正确标志的 GPU 硬件(以及其他位置)上高效实现,并且反过来,它影响了新 GPU 硬件提供的保证。因此,谈论内存模型的人可能会很兴奋,并且谈论比您主要关注的 C++11 问题更多的现代问题。

这是一个复杂的大话题。编写您认为可移植的代码真的很容易,但只能在特定平台上运行,或者通常只能在您测试过的平台上运行。但这只是因为线程很难。

关于c++ - c++ 11 atomic是否自动解决变量读写上的多核竞争?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53236113/

相关文章:

java - AWT-EventQueue 未从 Unsafe.park 唤醒

c++ - (为什么)我们可以在初始化时将非静态类成员分配给静态变量吗?

C++将长字符串传递给构造函数或setter

c++ - 赋值顺序

c++ - Qt C++ QPaint与QVector

c++ - 如何/何时使用虚拟析构函数?

c++ - 命令行程序的返回值

java - 可以停止使用 httpConnection.connect() 连接到 URL 的线程吗?

java - java中的初始化安全

c++ - 我收到一段代码的警告,但 bjarne stroustrup 的 c++ 书说它应该是一个错误。这里是什么?