【问题标题】:Negative duration with Boost Chrono's process_real_cpu_clockBoost Chrono 的 process_real_cpu_clock 的负持续时间
【发布时间】:2015-02-03 13:50:20
【问题描述】:

我正在尝试使用 Boost.Chrono 来测量我的代码的 CPU 时间。下面给出了我的 C++ 代码。问题是我有时会得到负持续时间作为输出。当我使用“process_real_cpu_clock”时会发生这种情况。当我使用“steady_clock”时,问题不会出现。我采取的一些输出如下:

第一次实施的时间:360 毫秒

第二次实施的时间:-3284.97 ms


第一次实施的时间:360 毫秒

第二次实施的时间:1010 毫秒


第一次实施的时间:-3924.97 ms

第二次实施的时间:1010 毫秒

只有第二个符合预期。我猜问题是关于持续时间的溢出,但是在第三个输出中,第一次实现的时间应该是第二次实现时间的 1/3 左右,如果我能看到第二次实现的时间,就不应该有溢出。 (我正在使用 Boost 1.54,并在 VirtualBox 上使用 Ubuntu)

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <boost/chrono.hpp>
#include <boost/chrono/process_cpu_clocks.hpp>

int main() {

int x,y,result,runs;
srand(time(NULL));
runs=1e7;


boost::chrono::process_real_cpu_clock::time_point start, start2; 
boost::chrono::process_real_cpu_clock::time_point end, end2;

start= boost::chrono::process_real_cpu_clock::now();

    for (int i=0;i<runs;i++) {

        x=rand() %100 +1;
        y=rand() %100 +1;
        auto dummy=x*y;
        result=(result+dummy)%50;
        } 
end=boost::chrono::process_real_cpu_clock::now();
boost::chrono::process_real_cpu_clock::duration diff=end-start;

start2= boost::chrono::process_real_cpu_clock::now();

    for (int i=0;i<(3*runs);i++) {

        x=rand() %100 +1;
        y=rand() %100 +1;
        auto dummy=x*y;
        result=(result+dummy)%50;

        } 
end2=boost::chrono::process_real_cpu_clock::now();

boost::chrono::process_real_cpu_clock::duration diff2=end2-start2;

     std::cout << "time for 1st implemention:"<<boost::chrono::duration <double, boost::milli> (diff).count()<< " ns" << std::endl;
     std::cout << "time for 2nd implementation:"<<boost::chrono::duration <double, boost::milli> (diff2).count()<< " ns" << std::endl;


return 0;
}

【问题讨论】:

  • 你确定这是代码吗? start1end1 在此处未使用。对代码进行适当的因式分解可避免此类容易出错的情况。我已经在我的答案中添加了这样一个考虑因素的解决方案(它可能对你的口味来说太笼统了)。
  • 你是对的。 start1end1 来自以前版本的代码。我修好了。

标签: c++ boost time chrono


【解决方案1】:

我怀疑你误用了boost::milli(这只是来自Boost Ratio 的通用比率)。

您想将 duration_cast 与 chrono 中的单位一起使用:

std::cout << "time for 1st implemention:" << duration_cast<nanoseconds>(diff).count() << " ns\n";
std::cout << "time for 2nd implementation:" << duration_cast<nanoseconds>(diff2).count() << " ns\n";

这是我的看法(选择毫秒以提高可读性):

Live On Coliru

#include <iostream>
#include <boost/chrono.hpp>
#include <boost/chrono/process_cpu_clocks.hpp>

using namespace boost::chrono;

template <typename R, typename P>
    static std::ostream& operator<<(std::ostream& os, duration<R,P> const& d) {
        return os << boost::chrono::duration_cast<boost::chrono::milliseconds>(d).count() << "ms";
    }

template <typename Clock = boost::chrono::process_cpu_clock, typename F, typename... Args>
nanoseconds bench(F&& f, Args&&... args) {
    auto start = Clock::now();

    volatile auto force = std::forward<F>(f)(std::forward<Args>(args)...);
    (void) force;

    return Clock::now() - start;
}

long long foo(int runs) {
    long long result = 0;
    for (int i = 0; i < runs; i++) {
        int x = rand() % 100 + 1;
        int y = rand() % 100 + 1;
        auto dummy = x * y;
        result = (result + dummy) % 50;
    }

    return result;
}

int main() {
    srand(time(NULL));

    std::cout << "1st method: " << bench(foo, 1e7)   << "\n";
    std::cout << "2nd method: " << bench(foo, 3e7) << "\n";
}

打印

1st method: 340ms
2nd method: 1010ms

【讨论】:

  • 感谢您的回答@sehe,但我得到的输出仍然很奇怪。其中一些是这样的:1st method: 503ms 2nd method: -1310ms1st method: -971ms 2nd method: 1574ms1st method: 503ms 2nd method: 99ms
  • 我只能想知道 VBox 下的实现错误/异常(尝试添加/不添加来宾、加速/CPU/芯片组虚拟化选项?),您可以在 Boost Chrono 提交工单
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
  • 2018-11-12
相关资源
最近更新 更多