正如标题所说,
一个典型的答案是:
允许任何和所有代码转换不会改变程序的可观察行为的规则
我们会不时地从某些实现中获取行为,这些行为归因于此规则.好多次错了.那么,这个规则究竟是什么呢.标准没有明确地将此规则作为一个部分或段落提及,那么究竟什么属于这条规则的范围?对我来说,这似乎是一个灰色区域,标准没有详细定义.有人可以根据标准的参考资料详细说明细节.
注意:将其标记为C和C++,因为它与两种语言都相关.
我想知道为什么没有编译器准备将相同值的连续写入合并到单个原子变量,例如:
#include <atomic>
std::atomic<int> y(0);
void f() {
auto order = std::memory_order_relaxed;
y.store(1, order);
y.store(1, order);
y.store(1, order);
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的每个编译器都会发出三次上面的编写.什么合法的,无种族的观察者可以看到上述代码与具有单次写入的优化版本之间的差异(即,不是"假设"规则适用)?
如果变量是易变的,那么显然不适用优化.在我的情况下有什么阻止它?
这是编译器资源管理器中的代码.
在这种情况下,两个负载会合二为一吗?如果这是依赖于架构的,那么说英特尔的现代处理器会是什么情况?我相信原子负载相当于英特尔处理器中的正常负载。
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()只是使用相同原子变量的两个负载的两个场景。编译器能否将这种两种加载的场景合并为一种加载并重用它?