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()只是使用相同原子变量的两个负载的两个场景。编译器能否将这种两种加载的场景合并为一种加载并重用它?
您的实施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目前还没有将这两种操作优化为一种。