This question already has an answer here:
这个问题在这里已有答案:
- Why don't compilers merge redundant std::atomic writes? 9 answers
- 为什么编译器没有合并多余的std :: atomic写入? 9个答案
Will the two loads be combined to one in such scenarios? If this is architecture dependent, what would be the case in say modern processors from say Intel? I believe atomic loads are equivalent to normal loads in Intel processors.
在这种情况下,两个负载是否会合并为一个?如果这是依赖于架构的,那么英特尔的现代处理器会出现什么情况呢?我相信原子负载相当于英特尔处理器的正常负载。
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()
and run2()
are simply two scenarios using two loads of the same atomic variable. Can the compiler collapse such scenarios of two loads into one load and reuse that?
run1()和run2()只是使用两个相同原子变量的两个场景。编译器是否可以将两个加载的场景折叠成一个加载并重用它?
2 个解决方案
#1
3
Can the compiler optimize away atomic loads?
Your implementation of run1()
can be safely optimized to
您可以安全地优化run1()的实现
void run1() {
auto a = atomic_var.load(std::memory_order_relaxed);
auto b = a;
// Some code using a and b;
}
In the original program the two loads could possibly be adjacent to each other in the total order of accesses on atomic_var
every time run1()
is called. In that case the adjacent load()
operations would return the same result.
在原始程序中,每次调用run1()时,两个加载可能在atomic_var上的访问总顺序中彼此相邻。在这种情况下,相邻的load()操作将返回相同的结果。
Since that possibility cannot be excluded, the compiler is allowed to optimize away the second load()
. This can be done for any memory order argument, not just for relaxed atomics.
由于不能排除这种可能性,因此允许编译器优化第二个load()。这可以针对任何内存顺序参数来完成,而不仅仅是为了放*子。
For run2()
it depends. You didn't specify /*some conditions*/
. If there's something, that might have a visible side effect on the atomic variable (like an opaque function call or accessing a volatile variable, etc.) then this cannot be optimized away. Otherwise it might be possible.
对于run2(),它取决于。你没有指定/ *某些条件* /。如果有什么东西,可能会对原子变量产生明显的副作用(比如不透明的函数调用或访问volatile变量等),那么就无法对其进行优化。否则它可能是可能的。
Does the compiler optimize out two atomic loads?
Depends on your compiler. And possibly on the compiler options you passed in. Possibly it depends on your platform. There is some debate going on, on whether compilers should optimize atomics. There is N4455 No Sane Compiler Would Optimize Atomics and this video as a start on the topic.
取决于您的编译器。可能还有你传入的编译器选项。可能它取决于你的平台。关于编译器是否应该优化原子,存在一些争论。 N4455没有Sane编译器将优化Atomics和这个视频作为主题的开始。
GCC and clang don't optimize the two load()
operations onto one at the moment.
GCC和clang目前不会将两个load()操作优化为一个。
#2
4
Neither GCC (6.3) nor Clang (3.9) currently optimizes the two loads into one.
目前,GCC(6.3)和Clang(3.9)都没有将两个负载优化为一个。
The only way to know is to look at the generated assembly: https://godbolt.org/g/nZ3Ekm
唯一的方法是查看生成的程序集:https://godbolt.org/g/nZ3Ekm
#1
3
Can the compiler optimize away atomic loads?
Your implementation of run1()
can be safely optimized to
您可以安全地优化run1()的实现
void run1() {
auto a = atomic_var.load(std::memory_order_relaxed);
auto b = a;
// Some code using a and b;
}
In the original program the two loads could possibly be adjacent to each other in the total order of accesses on atomic_var
every time run1()
is called. In that case the adjacent load()
operations would return the same result.
在原始程序中,每次调用run1()时,两个加载可能在atomic_var上的访问总顺序中彼此相邻。在这种情况下,相邻的load()操作将返回相同的结果。
Since that possibility cannot be excluded, the compiler is allowed to optimize away the second load()
. This can be done for any memory order argument, not just for relaxed atomics.
由于不能排除这种可能性,因此允许编译器优化第二个load()。这可以针对任何内存顺序参数来完成,而不仅仅是为了放*子。
For run2()
it depends. You didn't specify /*some conditions*/
. If there's something, that might have a visible side effect on the atomic variable (like an opaque function call or accessing a volatile variable, etc.) then this cannot be optimized away. Otherwise it might be possible.
对于run2(),它取决于。你没有指定/ *某些条件* /。如果有什么东西,可能会对原子变量产生明显的副作用(比如不透明的函数调用或访问volatile变量等),那么就无法对其进行优化。否则它可能是可能的。
Does the compiler optimize out two atomic loads?
Depends on your compiler. And possibly on the compiler options you passed in. Possibly it depends on your platform. There is some debate going on, on whether compilers should optimize atomics. There is N4455 No Sane Compiler Would Optimize Atomics and this video as a start on the topic.
取决于您的编译器。可能还有你传入的编译器选项。可能它取决于你的平台。关于编译器是否应该优化原子,存在一些争论。 N4455没有Sane编译器将优化Atomics和这个视频作为主题的开始。
GCC and clang don't optimize the two load()
operations onto one at the moment.
GCC和clang目前不会将两个load()操作优化为一个。
#2
4
Neither GCC (6.3) nor Clang (3.9) currently optimizes the two loads into one.
目前,GCC(6.3)和Clang(3.9)都没有将两个负载优化为一个。
The only way to know is to look at the generated assembly: https://godbolt.org/g/nZ3Ekm
唯一的方法是查看生成的程序集:https://godbolt.org/g/nZ3Ekm