我正在创建一个小程序来衡量类型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));
}
Run Code Online (Sandbox Code Playgroud)
其余的代码可以在这里找到:main.cpp.
回应@Neil Butterworth.即使在使用副本时,我仍然认为编译器可以轻松避免复制:
for (std::size_t idx = 0; idx < n; ++idx)
{
// gcc won't remove this copy?
Container copy = inContainer;
gNumCopies += copy.size();
}
Run Code Online (Sandbox Code Playgroud)
C++ 03标准表示对易失性数据的读写是可观察的行为(C++ 2003,1.9 [intro.execution]/6).我相信这可以保证无法优化对易失性数据的分配.另一种可观察行为是对I/O函数的调用.在这方面,C++ 11标准更加明确:在1.9/8中它明确地说明了这一点
对符合实现的最低要求是:
- 严格根据抽象机器的规则来评估对易失性对象的访问.
如果编译器可以证明代码不会产生可观察的行为,那么它可以优化代码.在您的更新中(不使用volatile),复制构造函数和其他函数调用以及重载操作符可能会避免任何I/O调用和对volatile数据的访问,编译器可能会很好地理解它.但是,如果gNumCopies是后来在具有可观察行为(例如打印)的表达式中使用的全局变量,则不会删除此代码.
| 归档时间: |
|
| 查看次数: |
7215 次 |
| 最近记录: |