编译器是否可以优化两个原子负载?
Can and does the compiler optimize out two atomic loads?
在这种情况下,两个负载会合二为一吗?
如果这取决于体系结构,那么来自英特尔的现代处理器会是什么情况?我相信原子负载相当于英特尔处理器中的正常负载。
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()
只是使用同一原子变量的两次加载的两种情况。编译器能否将这种两载的场景合并为一载重用?
GCC (6.3) 和 Clang (3.9) 目前都没有将两个负载优化为一个。
唯一知道的方法是查看生成的程序集:https://godbolt.org/g/nZ3Ekm
编译器可以优化掉原子负载吗?
您对 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()
操作会 return 相同的结果。
由于不能排除这种可能性,允许编译器优化掉第二种load()
。这可以用于任何内存顺序参数,而不仅仅是用于松散的原子。
对于 run2()
这取决于。您没有指定 /*some conditions*/
。如果有什么东西可能会对原子变量产生可见的副作用(比如不透明的函数调用或访问 volatile 变量等),那么就无法将其优化掉。否则它可能是可能的。
编译器是否优化了两个原子加载?
取决于您的编译器。并且可能取决于您传入的编译器选项。可能取决于您的平台。关于编译器是否应该优化原子的争论正在进行中。该主题以 N4455 No Sane Compiler Would Optimize Atomics and this video 开头。
GCC 和 clang 目前并未将两个 load()
操作优化为一个。
在这种情况下,两个负载会合二为一吗? 如果这取决于体系结构,那么来自英特尔的现代处理器会是什么情况?我相信原子负载相当于英特尔处理器中的正常负载。
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()
只是使用同一原子变量的两次加载的两种情况。编译器能否将这种两载的场景合并为一载重用?
GCC (6.3) 和 Clang (3.9) 目前都没有将两个负载优化为一个。
唯一知道的方法是查看生成的程序集:https://godbolt.org/g/nZ3Ekm
编译器可以优化掉原子负载吗?
您对 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()
操作会 return 相同的结果。
由于不能排除这种可能性,允许编译器优化掉第二种load()
。这可以用于任何内存顺序参数,而不仅仅是用于松散的原子。
对于 run2()
这取决于。您没有指定 /*some conditions*/
。如果有什么东西可能会对原子变量产生可见的副作用(比如不透明的函数调用或访问 volatile 变量等),那么就无法将其优化掉。否则它可能是可能的。
编译器是否优化了两个原子加载?
取决于您的编译器。并且可能取决于您传入的编译器选项。可能取决于您的平台。关于编译器是否应该优化原子的争论正在进行中。该主题以 N4455 No Sane Compiler Would Optimize Atomics and this video 开头。
GCC 和 clang 目前并未将两个 load()
操作优化为一个。