编译器是否消除了不必要的原子?

时间:2018-06-16 11:46:06

标签: c++ multithreading c++11 atomic compiler-optimization

如果我声明一个仅在单个线程中使用的原子变量,那么编译器是否能够对其进行优化,并在某些情况下将std::atomic<T>替换为T

我读过一些关于激励的编译器优化的文章,但它们主要是关于锁和存储的重新排序和分组,而不是关于消除它们。

我们以std:shared_pointer为例。它有一个原子计数器,但是如果只有一个线程可以访问它,它可以用一个简单的计数器代替,它仍然会表现得像原子一样。

1 个答案:

答案 0 :(得分:1)

答案取决于你认为优化原子的假设。使用atomics有两个作用:强制执行语句的可观察顺序并确保处理器缓存失效。

如果您使用的是英特尔处理器,则可以简单地删除大多数后者。这是因为处理器保证了相同的行为,并且不需要进行特定的处理。

然而,对于订购,有一个不同的故事。为了消除排序约束,您的编译器应该能够证明您没有不同的可观察行为。

实际上,如果您将指针或引用传递给另一个编译单元中的函数,则编译器无法进行优化。另一方面,如果编译器对使用情况具有完全可见性,则可以得出结论:不需要内存屏障,并基于此消除它们。

解决codegen问题是一个容易解决的问题,而且我意识到大多数行业编译器至少都有一些支持。 消除另一端的内存障碍是即将离任的研究的一部分,因此您可能无法获得或者可能只涵盖非常简单的案例。

正如您所询问的那样,认为您对用例更了解可能是合理的。但是,我建议在需要原子行为时保持原子。手动优化这一点非常耗时,但好处可能并不明显。