13
C ++ volatile关键字是否引入了内存屏障?
我了解这会volatile告知编译器该值可能会更改,但是为了完成此功能,编译器是否需要引入内存隔离墙以使其起作用? 据我了解,对易失对象的操作顺序不能重新排序,必须保留。这似乎意味着需要一些内存隔离,并且实际上没有解决方法。我说的对吗? 有关这个问题有一个有趣的讨论 乔纳森·韦克利(Jonathan Wakely)写道: ...对不同的volatile变量的访问,只要它们出现在单独的完整表达式中,就无法重新排序...对,volatile对于线程安全性是无用的,但并非出于其给出的原因。这不是因为编译器可能会重新排列对易失性对象的访问,而是因为CPU可能会重新排列对易失性对象的访问。原子操作和内存屏障可防止编译器和CPU重新排序 到大卫·施瓦茨回答的评论: 从C ++标准的角度来看,在编译器执行某些操作和编译器发出导致硬件执行某些操作的指令之间没有区别。如果CPU可以重新排序对易失性的访问,则该标准不需要保留其顺序。... ... C ++标准对重新排序没有任何区别。而且您不能说CPU可以对它们进行重新排序而不会产生可观察的效果,所以没关系-C ++标准将它们的顺序定义为可观察的。如果编译器生成使平台执行标准要求的代码,则它符合平台上的C ++标准。如果该标准要求对挥发物的访问不进行重新排序,那么重新排序它们的平台将不兼容。... 我的观点是,如果C ++标准禁止编译器对不同的volatile进行重新排序,那么从理论上讲,此类访问的顺序是程序可观察到的行为的一部分,那么它还要求编译器发出禁止CPU执行的代码所以。该标准没有区分编译器做什么和编译器生成的代码使CPU做什么。 哪个产生两个问题:它们中的一个是“正确的”吗?实际的实现实际上是做什么的?