编译器是否可以优化两个原子负载?

the*_*ang 6 c++ x86 gcc atomic compiler-optimization

在这种情况下,两个负载会合二为一吗?如果这是依赖于架构的,那么说英特尔的现代处理器会是什么情况?我相信原子负载相当于英特尔处理器中的正常负载。

void run1() {
    auto a = atomic_var.load(std::memory_order_relaxed);
    auto b = atomic_var.load(std::memory_order_relaxed);
   // Some code using a and b;
}

void run2() {
    if (atomic_var.load(std::memory_order_relaxed) == 2 && /*some conditions*/ ...) {
         if (atomic_var.load(std::memory_order_relaxed) * somevar > 3) {
               /*...*/
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

run1()并且run2()只是使用相同原子变量的两个负载的两个场景。编译器能否将这种两种加载的场景合并为一种加载并重用它?

Ral*_*zky 5

编译器可以优化原子负载吗?

您的实施run1()可以安全地优化为

void run1() {
    auto a = atomic_var.load(std::memory_order_relaxed);
    auto b = a;
   // Some code using a and b;
}
Run Code Online (Sandbox Code Playgroud)

atomic_var在原始程序中,两个加载可能在每次run1()调用时的访问总顺序中彼此相邻。在这种情况下,相邻的load()操作将返回相同的结果。

由于不能排除这种可能性,因此允许编译器优化掉第二个load(). 这可以针对任何内存顺序参数来完成,而不仅仅是针对宽松原子。

因为run2()这取决于。你没有指定/*some conditions*/。如果有什么东西可能会对原子变量产生明显的副作用(例如不透明的函数调用或访问易失性变量等),那么就无法对其进行优化。否则也许有可能。

编译器是否优化了两个原子加载?

取决于你的编译器。可能取决于您传入的编译器选项。可能取决于您的平台。关于编译器是否应该优化原子存在一些争论。有N4455 没有健全的编译器会优化原子这个视频作为该主题的开始。

load()GCC 和 clang目前还没有将这两种操作优化为一种。