C++ 其他线程是否会在合理的时间内看到对“volatile”字大小的变量的写入?
当问到一个问题时,我发现这是人们不确定的核心问题 可以做出以下假设:C++ 其他线程是否会在合理的时间内看到对“volatile”字大小的变量的写入?,c++,multithreading,c++03,lock-free,C++,Multithreading,C++03,Lock Free,当问到一个问题时,我发现这是人们不确定的核心问题 可以做出以下假设: CPU确实使用了一种缓存一致性协议,如MESI(F)(示例:x86/x86_64和ARMv7mp) 假设变量的大小由处理器原子地写入/读取(对齐和本机字大小) 变量声明为易变的volatile 问题是: 如果我在一个线程中写入变量,其他线程会看到更改吗 其他线程将看到更改的时间范围的数量级是多少 您知道缓存一致性不足以确保跨CPU/跨核心可见性的体系结构吗 问题不是: 使用这样的变量安全吗 关于重新排序问题 关于C+
- CPU确实使用了一种缓存一致性协议,如MESI(F)(示例:x86/x86_64和ARMv7mp)
- 假设变量的大小由处理器原子地写入/读取(对齐和本机字大小)
- 变量声明为易变的
volatile
- 如果我在一个线程中写入变量,其他线程会看到更改吗
- 其他线程将看到更改的时间范围的数量级是多少
- 您知道缓存一致性不足以确保跨CPU/跨核心可见性的体系结构吗
- 使用这样的变量安全吗
- 关于重新排序问题
- 关于C++11原子
我想说不,没有保证。有些实现使用多台独立计算机,共享数据必须通过网络传输(通常非常快)计算机之间的连接。在这种情况下,您会尝试仅在需要时传输数据。例如,这可能由互斥锁和标准原子函数触发,但希望不是通过存储到任意本地内存,也可能不是通过存储到易失性内存
我可能错了,但你必须证明我错了。假设现在的x86/64: 如果我在一个线程中写入变量,其他线程会看到更改吗 是的。假设您使用的是一个现代的、不太旧的/有缺陷的编译器 其他线程将看到更改的时间范围的数量级是多少 这真的取决于你如何衡量。 基本上,这是相同NUMA节点上的内存延迟时间=200个周期。在另一个节点上,在2节点框上,大约是两倍。在更大的框上可能有所不同。 如果您的写入相对于时间测量点被重新排序,您可以得到+/-50个周期 几年前我测量过这个,在3GHz的盒子上得到60-70ns,在另一个节点上得到了两倍 您知道缓存一致性不足以确保跨cpu/跨核心可见性的体系结构吗 我认为缓存一致性的含义是可见性。话虽如此,我不确定Sun risk机器是否具有与x86相同的缓存一致性和宽松的内存模型,因此我会非常仔细地对它们进行测试。具体来说,您可能需要添加内存释放障碍,以强制刷新内存写入 如果我在一个线程中写入变量,其他线程会看到更改吗 没有保证。如果你认为有,告诉我你在哪里找到的 其他线程将看到更改的时间范围的数量级是多少 不可能,也不能保证 您知道缓存一致性不足以确保跨cpu/跨核心可见性的体系结构吗
这是一个不相干的问题,因为你在谈论C++代码中必须编译成汇编代码的操作。即使你有应用于汇编代码的硬件保证,也不能保证这些保证“通过”到C++代码。
但就这个问题可以回答的程度而言,答案是肯定的。在真实的平台中存在着发布写入、读取预取和其他类型的缓存(例如编译器对寄存器的操作)。根据您描述的假设,不能保证在一个线程中写入
volatile
变量会被“看到”“另一方面
鉴于此,您的第二个问题(关于时间范围)不适用
对于(多处理器)PowerPC体系结构,缓存一致性不足以确保易失性
变量的跨核可见性。需要执行明确的指令以确保状态被刷新(并使其在多个处理器及其缓存中可见)
实际上,在需要执行此类指令的体系结构上,数据同步原语(互斥、信号量、关键部分等)的实现确实使用了这些指令
更广泛地说,C++中的<>代码> Value< /Cord>关键字与多线程无关,更不用说与交叉缓存一致性有关的任何东西了。代码>易失性,在给定的执行线程中,转换为需要获取和写入未被编译器消除或重新排序的变量(这会影响优化)。它不会转化为任何关于在执行线程之间完成获取或写入的顺序或同步的要求,而这些要求是缓存一致性所必需的
从理论上讲,可以实现一个编译器来提供这样的保证。我还没有看到任何关于这样做的信息——这并不奇怪,因为提供这样的保证会通过强制线程之间的同步严重影响多线程代码的性能——即使