编译器能否优化掉两个原子加载操作?

8
在这种情况下,这两个负载将合并为一个吗?如果这取决于架构,那么在比如来自英特尔的现代处理器中会是什么情况呢?我相信原子负载在英特尔处理器中等同于普通负载。
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) {
               /*...*/
         }
    }
}

run1()run2()仅是使用相同原子变量的两种情景。编译器是否能够折叠这样的两个加载场景成一个加载并重用它?


抱歉,你为什么同时有run1run2?你能在你的问题中更具体一些吗? - Brian Bi
@Brian 只有两种情况。已编辑。 - themagicalyang
2个回答

5

编译器能够优化掉原子加载吗?

您对run1()的实现可以安全地进行优化,以便于

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

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

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

对于 run2(),情况取决于您未指定的 /*some conditions*/。如果有某些内容可能对原子变量具有可见的副作用(例如不透明函数调用或访问易失性变量等),则无法进行优化。否则可能是可行的。

编译器是否会优化掉两个原子负载?

这取决于您的编译器,可能还取决于您传递的编译器选项,以及您的平台。目前有一些争议,关于编译器是否应该优化原子操作。可以从N4455 No Sane Compiler Would Optimize Atomicsthis video开始了解相关主题。

目前GCC和clang不会将两个load()操作优化为一个。


目前的答案是标准允许,但现代编译器不这样做,这仍然是一个讨论的话题。 - themagicalyang
那可能是正确的。至少在这种情况下,它们没有进行太多优化。也许在其他情况下会有所不同。当然,现代优化编译器可以根据其内存排序将存储和加载重新排序。对于C++程序员而言,C++标准是编写代码的接口。依赖编译器是否对某些内容进行优化通常不是一个好主意,因为否则任何新的编译器更新都可能引入错误。 - Ralph Tandetzky
最近有一个问题询问了关于合并重复存储的事情。我在那里的回答基本上与你在这里的回答相同,包括链接N4455(但也包括http://wg21.link/p0062)。还有一些关于*为什么*编译器选择不这样做的内容,直到这个问题得到解决。 - Peter Cordes
无论如何,我将此关闭为新问题的重复。 - Peter Cordes
“目前有一些争议,关于编译器是否应该优化原子操作”,但在这种简单情况下,没有争议的是优化是有效的。 - curiousguy

4

目前,GCC(6.3)和Clang(3.9)都没有将这两个加载项优化成一个的功能。

唯一的方法是查看生成的汇编代码:https://godbolt.org/g/nZ3Ekm


这符合标准吗?volatile 不是说每次都需要加载吗?为什么原子操作也要算进去? - themagicalyang
2
@themagicalyang:std::atomic 不一定需要使用 volatile,并且应该可以在 memory_order_relaxed 下结合两个加载。如果你愿意,你可以在 GCC 的错误跟踪器上提交报告,并查看他们的回复。如果你这么做了,请确保在这里提供链接! - John Zwinck
1
如果您想要一个 volatile std::atomic<int>,那么请使用它。但是,您忽略了 atomic_var 的定义,因此我们没有理由认为它是 volatile 的。 - MSalters
4
这方面的许多信息都可以在JF Bastien的卓越文章中找到:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4455.html。 - Matt Godbolt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接