C++ 为什么在获取系统时间时在这里使用“原子信号围栏”

C++ 为什么在获取系统时间时在这里使用“原子信号围栏”,c++,concurrency,atomic,barrier,C++,Concurrency,Atomic,Barrier,我在实现无锁队列的中找到了此函数。此函数使用QueryPerformanceCounter获取准确的系统时间 #define CompilerMemBar() std::atomic_signal_fence(std::memory_order_seq_cst) SystemTime getSystemTime() { LARGE_INTEGER t; CompilerMemBar(); if (!QueryPerformanceCounter(&t)) {

我在实现无锁队列的中找到了此函数。此函数使用
QueryPerformanceCounter
获取准确的系统时间

#define CompilerMemBar() std::atomic_signal_fence(std::memory_order_seq_cst)
SystemTime getSystemTime()
{
    LARGE_INTEGER t;
    CompilerMemBar();
    if (!QueryPerformanceCounter(&t)) {
        return static_cast<SystemTime>(-1);
    }
    CompilerMemBar();

    return static_cast<SystemTime>(t.QuadPart);
}
定义编译器mbar()标准::原子信号围栏(标准::内存顺序) SystemTime getSystemTime() { 大整数t; 编译器mbar(); if(!QueryPerformanceCounter(&t)){ 返回静态_cast(-1); } 编译器mbar(); 返回静态_型铸件(t.QuadPart); }
我注意到有两个
编译器mbar()
,我认为这是为了防止编译器重新排序。然而,在我在github上搜索了一些代码之后,我发现使用编译器屏障包装
QueryPerformanceCounter
可能不是一种常见的做法。所以我的问题是这些障碍是用来处理一些特殊情况的?是否可能重新排序会影响我们获得的系统时间精度?但是我不知道他们会怎么做,因为我认为即使WINAPI调用或return语句被重新排序,它似乎对精度没有影响。

代码开发人员可能认为,如果编译器不能重新排序语句,它将产生更准确的结果。。 例如:

expensive1(); // takes a lot of time

SystemTime t = getSystemTime();

expensive2();
如果希望在两个昂贵调用之间获得准确的时间戳(或性能计数),则不希望编译器对其中一个调用重新排序
getSystemTime()
因为它可能会影响
QueryPerformanceCounter
返回的值

我不知道这是否现实。编译器必须知道函数内部发生了什么,否则它不会对任何内容重新排序 (如果在预编译库中定义了
昂贵的
调用,则不会对语句进行重新排序)

但至少这种方法似乎没有造成多大危害。
std::atomic\u signal\u fence(std::memory\u order\u seq\u cst)
阻止编译器重新排序,但它不会生成CPU fence指令。

fyi:这里有很多关于旧系统和
QueryPerformanceCounter
的注意事项,这可能是一种修复/解决方法的尝试。