c++ - 对共享数据的线程安全访问 - 读/写实际上发生并且不会发生重新排序

标签 c++ multithreading compiler-construction thread-safety volatile

从这里:https://stackoverflow.com/a/2485177/462608

For thread-safe accesses to shared data, we need a guarantee that
the read/write actually happens (that the compiler won't just store the value in a register instead and defer updating main memory until much later)
that no reordering takes place. Assume that we use a volatile variable as a flag to indicate whether or not some data is ready to be read. In our code, we simply set the flag after preparing the data, so all looks fine. But what if the instructions are reordered so the flag is set first?

  • 在什么情况下编译器会将值存储在寄存器中并推迟更新主内存? [关于上述引用]
  • 上面引用的“重新排序”是什么?什么情况下会发生?

最佳答案

问:在什么情况下编译器会将值存储在寄存器中并推迟更新主内存?

答:(这是一个广泛且开放式的问题,可能不太适合 stackoverflow 格式。)简短的答案是,每当源语言(C++ 每个你的标签)允许它并且编译器认为它是有利可图的。

问:上面引用的“重新排序”是什么?

答:编译器和/或 CPU 发出加载和存储指令的顺序与原始程序源的一对一翻译所规定的顺序不同。

问:什么情况下会发生?

答:对于编译器来说,与第一个问题的答案类似,只要原始程序语义允许并且编译器认为它是有利可图的。对于 CPU 来说也是类似的,根据架构内存模型,只要原始(单线程!)结果相同,CPU 通常可以对内存访问进行重新排序。例如,编译器和 CPU 都可以尝试尽早提升负载,因为加载延迟通常对性能至关重要。

为了执行更严格的排序,例如为了实现同步原语,CPU 提供各种原子 和/或栅栏 指令,并且编译器可以根据编译器和源语言提供禁止重新排序的方法。

关于c++ - 对共享数据的线程安全访问 - 读/写实际上发生并且不会发生重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10780728/

相关文章:

c++ - 根据参数对数字类型列表进行操作

c++ - 是否可以多线程同时执行非void函数? (C++)

c++ - 用 C/C++ 中的地址调用 lua 函数?

c - 尝试使指针为 NULL 时赋值错误中的左值无效

gcc - yylval 未定义,带有 flex 和 bison

c++ - GCC 4.8 中 C++11 thread_local 变量的性能损失是多少?

multithreading - 改变 Clojure 的 ref 的线程越多,每个线程的重试率上升得越多?

python - python 2.7下xmlrpclib.ServerProxy的多线程问题

c# - 我不了解 volatile 和 Memory-Barrier 的是

Android 手机的 Java 编译器