synchronization - 线程同步: How to guarantee visibility of writes

标签 synchronization thread-safety cpu-architecture memory-barriers memory-model

已经有很多关于软件和硬件内存模型、内存栅栏、存储/加载重新排序等的信息。但是,这一切似乎都集中在保证共享内存读写的相对顺序上。

对于这样的系统来说,将线程的写入完全延迟很长时间是否合法?

例如,考虑一个线程对内存中的数据结构进行一些更新,然后引发一个应该通知其他线程更新的标志:

(dataWritten is initially false)
store value1
store value2
store value3
mfence
store dataWritten (true)

根据我读过的大多数内存模型,内存屏障保证任何其他线程无法将 dataWritten 观察为 true,同时仍然读取过时的值 1、2 或 3,即,它使这些写入成为原子的。

但是我可以确定写入内容会被看到吗?在内存模型下,只要标志不早于值写入,无限期地延迟写入是否合法?

用数据库术语来说,内存模型是否可以用于推断持久性(除了原子性和一致性之外,可以通过使用内存栅栏和标志来保证,如上例所示)?

更新: Detailed semantics of volatile regarding timeliness of visibility在 Java 内存模型的上下文中解决了相同的主题,并且 Memory model ordering and visibility?对于 C++11。该讨论是否也适用于硬件内存模型,即 CPU ISA 是否只为正确的可见性序列提供硬保证,但为延迟可见性提供“软”保证?

最佳答案

很难证明是否定的——有很多指令集架构。但是,我怀疑您是对的,没有硬件内存模型可以保证写入的最终可见性。

我强烈推荐阅读A Formal Specification of Intel® Itanium® Processor Family Memory Ordering ,因为尽管您可能不关心 Itanium,但它对硬件内存模型通常关心的保证进行了出色且可读的描述。

实际上,只要 CPU 仍在执行指令,它最终就必须刷新其写入。此外,只要写入已命中 L2 高速缓存或附近,由于高速缓存一致性协议(protocol),它通常应该对其他 CPU 可见。所以我认为这不是特别值得担心的事情。

关于synchronization - 线程同步: How to guarantee visibility of writes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13009411/

相关文章:

javascript - 一个 Backbone 模型用于多个 View ,谁处理 fetch()?

java - Java多线程-运行线程仅按顺序运行方法一次

c++ - 如何为不可变类型实现std::atomic <T>::operator =?

cpu - 计算机CPU中的寄存器

performance - "Jump if zero"(jz) 更快吗?

caching - MESI在Intel 64和IA-32上的意义是什么

python - 关于为什么 Lock 机制没有在下面的 python 脚本中实现的任何建议?

java - 等待计时器在 Java 中完成

java - Collections.synchronizedList 与 vector

javascript - JavaScript 中的事件计时