0

我想确定下面的代码是否允许 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;
}
4

2 回答 2

1

在 C 标准 C11 5.1.2.3/2 中,访问易失性内存位置算作副作用:

“访问易失性对象、修改对象、修改文件或调用执行任何这些操作的函数都是副作用”

并且不允许编译器生成导致额外副作用的代码。明确不允许生成导致对 volatile 变量的额外访问的代码 (C11 5.1.2.3/6)。

但是你使用的是 VC++,所以所有的赌注都没有了。它几乎不遵循任何标准。如果可能的话,我建议改用严格遵守的 C 编译器。

于 2012-06-11T06:27:29.073 回答
0

C 语言中没有任何内容指定此级别的内存系统行为,也没有任何关于线程的内容,因此没有确定的答案。

可以肯定的是,您需要 CPU、操作系统和编译器的确切详细信息。

但是,我怀疑任何现代架构都会从内存中获取两次以服务于您提到的任何目的,前提是计算不会中断。第一个之后的任何引用都将被缓存。

但是,如果在unsafe_variablefetch 开始之后但_varSize可以使用之前存在上下文切换,则可以想象,当该线程继续时,fetch 可能会重新启动。

于 2012-06-11T05:58:11.227 回答