【发布时间】:2011-09-02 01:45:18
【问题描述】:
我正在创建一个小程序来测量 boost::shared_ptr 和 boost::intrusive_ptr 类型的容器之间的性能差异。为了防止编译器优化掉副本,我将变量声明为 volatile。循环如下所示:
// TestCopy measures the time required to create n copies of the given container.
// Returns time in milliseconds.
template<class Container>
time_t TestCopy(const Container & inContainer, std::size_t n) {
Poco::Stopwatch stopwatch;
stopwatch.start();
for (std::size_t idx = 0; idx < n; ++idx)
{
volatile Container copy = inContainer; // Volatile!
}
// convert microseconds to milliseconds
return static_cast<time_t>(0.5 + (double(stopwatch.elapsed()) / 1000.0));
}
其余代码可以在这里找到:main.cpp。
- 在此处使用 volatile 会阻止编译器优化副本吗?
- 是否存在可能导致结果无效的陷阱?
更新
回应@Neil Butterworth。即使在使用副本时,在我看来编译器仍然可以轻松避免副本:
for (std::size_t idx = 0; idx < n; ++idx)
{
// gcc won't remove this copy?
Container copy = inContainer;
gNumCopies += copy.size();
}
【问题讨论】:
-
在编译器中使用 -O0 和 -g 标志不起作用吗?我不认为在这里使用 volatile 是正确的方法。
-
@RC 而不是使用
-O0进行分析,您可以只猜测性能影响。结果同样与现实场景无关。 -
@RC 我不确定。我知道,即使使用 -O0,像 RVO 这样的优化也会发挥作用(参见stackoverflow.com/questions/4767620/…)。
-
如果拷贝构造函数有副作用,编译器是否允许优化掉拷贝?
-
@Neil,你能详细说明一下吗?具体来说,我认为 12.8/15 中列出的任何一个条件都不适用于这种情况。没有返回语句,也没有临时对象。此外,请考虑 ideone.com/aJBr1 。即使使用
g++ -O4,复制构造函数也会在每个循环中调用一次。 (旁白:是的,如果有问题的Container有一个没有副作用的复制构造函数,则可以按照 1.9/1 和 1.9/6 对其进行优化。但是,我问的是有副作用的复制构造函数.)
标签: c++