使用volatile来防止基准测试代码中的编译器优化? [英] Using volatile to prevent compiler optimization in benchmarking code?

查看:118
本文介绍了使用volatile来防止基准测试代码中的编译器优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个小程序来测量 boost :: shared_ptr boost :: intrusive_ptr 。为了防止编译器优化副本,我将变量声明为volatile。循环如下所示:

I am creating a little program measure the performance difference between containers of types boost::shared_ptr and boost::intrusive_ptr. In order to prevent the compiler from optimizing away the copy I declare the variable as volatile. The loop looks like this:

// 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

The rest of the code can be found here: main.cpp.


  • 在这里使用volatile会阻止编译器优化副本吗?

  • 是否存在任何可能使结果无效的陷阱? / li>
  • Will using volatile here prevent the compiler from optimizing away the copy?
  • Are there any pitfalls that may invalidate the results?

响应@Neil Butterworth。即使在使用副本时,在我看来,编译器仍然可以轻松避免该副本:

In response to @Neil Butterworth. Even when using the copy it still seems to me that the compiler could easily avoid the copy:

for (std::size_t idx = 0; idx < n; ++idx)
{
    // gcc won't remove this copy?
    Container copy = inContainer;
    gNumCopies += copy.size();        
}


推荐答案

C ++ 03标准表示对易失性数据进行读写是可以观察到的行为(C ++ 2003,1.9 [intro.execution] / 6)。我相信,这保证了无法优化分配给易失数据的工作。另一种可观察到的行为是对I / O函数的调用。
在这方面,C ++ 11标准更加明确:在1.9 / 8中,它明确指出

The C++03 standard says that reads and writes to volatile data is observable behavior (C++ 2003, 1.9 [intro.execution] / 6). I believe this guarantees that assignment to volatile data cannot be optimized away. Another kind of observable behavior is calls to I/O functions. The C++11 standard is even more unambiguous in this regard: in 1.9/8 it explicitly says that


符合标准的实现的要求如下:

—严格根据抽象机的规则评估对易失对象的访问。

The least requirements on a conforming implementation are:
— Access to volatile objects are evaluated strictly according to the rules of the abstract machine.

如果编译器可以证明代码没有产生可观察到的行为,那么它可以优化代码。在您的更新中(不使用volatile),复制构造函数和其他函数调用&重载的运算符可能会避免任何I / O调用和对易失性数据的访问,并且编译器可能会很好地理解它。但是,如果 gNumCopies 是稍后在具有可观察到的行为(例如打印)的表达式中使用的全局变量,则不会删除此代码。

If a compiler can prove that a code does not produce an observable behavior then it can optimize the code away. In your update (where volatile is not used), copy constructor and other function calls & overloaded operators might avoid any I/O calls and access to volatile data, and the compiler might well understand it. However if gNumCopies is a global variable that later used in an expression with observable behavior (e.g. printed), then this code will not be removed.

这篇关于使用volatile来防止基准测试代码中的编译器优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆