编译器可以并且确实优化了两个原子载荷吗?

时间:2017-01-24 05:20:28

标签: c++ gcc x86 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) {
               /*...*/
         }
    }
}

run1()run2()只是使用两个相同原子变量的两个场景。编译器是否可以将两个加载的场景折叠到一个加载中并重用它?

2 个答案:

答案 0 :(得分:4)

GCC(6.3)和Clang(3.9)目前都没有将两个负载优化为一个。

要知道的唯一方法是查看生成的程序集:https://godbolt.org/g/nZ3Ekm

答案 1 :(得分:3)

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

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

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

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

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

取决于/*some conditions*/。您没有指定load()。如果有什么东西,可能会对原子变量产生明显的副作用(比如不透明的函数调用或访问volatile变量等),那么就无法对其进行优化。否则它可能是可能的。

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

取决于您的编译器。可能还有你传入的编译器选项。可能它取决于你的平台。关于编译器是否应该优化原子,存在一些争论。有N4455 No Sane Compiler Would Optimize Atomicsthis video作为主题的开头。

GCC和clang目前还没有优化两个db.mongoAuditEvent.aggregate([ {$group: {_id : "$corrId", currentEvent: {"$last": "$event.status"}, events: { $push: "$$ROOT"} }}, {$sort: {"timestamp": 1} }, {$skip: 0 }, {$limit: 10} ], {allowDiskUse: true}).pretty() 操作。