我想确定下面的代码是否允许CPU两次获取unsafe_variable?让我们假设编译器不会重新排序或优化代码,因为volatile和_ReadWriteBarrier(在VS上)。 Mutex不能在这里使用,我只关心潜在的双重获取的情况。
我不是CPU设计方面的专家,但我对潜在双重提取的关注点是:推测执行(性能优化技术包括分支预测和预取技术),寄存器和内存位置重命名以及使用在一个或两个CPU中重新排序缓冲区和存储缓冲区?请告诉我这里是否可以双击。
int function(void* Data) {
size_t _varSize = ((volatile DATA *)Data)->unsafe_variable;
// unsafe_variable is in some kind of shared memory and can change at any time
_ReadWriteBarrier();
// this does not prevent against CPU optimisations (MemoryBarrier would)
if (_varSize > x * y) { return FALSE;}
size_t size = _varSize - t * q;
function_xy(size);
return TRUE;
}
答案 0 :(得分:1)
在C标准C11 5.1.2.3/2中访问易失性存储器位置计为副作用:
“访问易失性对象,修改对象,修改文件或调用函数 任何这些操作都是副作用“
并且不允许编译器生成导致其他副作用的代码。显然不允许生成导致对volatile变量进行额外访问的代码(C11 5.1.2.3/6)。
但是你正在使用VC ++所以所有的赌注都没有了。它几乎没有遵循任何标准。如果可能的话,我建议使用严格符合C编译器。
答案 1 :(得分:0)
C语言中没有任何内容指定此级别的内存系统行为,也没有任何关于线程的内容,因此没有确定的答案。
确定您需要CPU,操作系统和编译器的确切详细信息。
但是,我怀疑任何现代架构都会从内存中获取两次以满足您提及的任何目的,前提是计算不会被计算。第一个之后的任何引用都是缓存。
但是,如果在unsafe_variable
提取开始之后但在使用_varSize
之前存在上下文切换,则可以想象当此线程继续时可能会重新启动提取。