【问题标题】:Measurement with boost::posix_time::microsec_clock has error more than ten microseconds?boost::posix_time::microsec_clock 的测量误差超过十微秒?
【发布时间】:2012-10-09 22:45:35
【问题描述】:

我有以下代码:

long long unsigned int GetCurrentTimestamp()
{
   LARGE_INTEGER res;
   QueryPerformanceCounter(&res);
   return res.QuadPart;
}


long long unsigned int initalizeFrequency()
{
   LARGE_INTEGER res;
   QueryPerformanceFrequency(&res);
   return res.QuadPart;
}


//start time stamp
boost::posix_time::ptime startTime = boost::posix_time::microsec_clock::local_time();
long long unsigned int start = GetCurrentTimestamp();


// ....
// execution that should be measured
// ....

long long unsigned int end = GetCurrentTimestamp();
boost::posix_time::ptime endTime = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration duration = endTime - startTime;
std::cout << "Duration by Boost posix: " << duration.total_microseconds() <<std::endl;
std::cout << "Processing time is " << ((end - start) * 1000000 / initalizeFrequency()) 
            << " microsec "<< std::endl;

这段代码的结果是

Duration by Boost posix: 0
Processing time is 24 microsec

为什么会有这么大的分歧? Boost 很糟糕,它应该测量微秒,但它测量微秒,误差只有十分之一微秒???

【问题讨论】:

    标签: c++ winapi boost time


    【解决方案1】:

    Posix 时间:微秒时钟:

    使用亚秒级分辨率时钟获取 UTC 时间。在 Unix 系统上,这是使用 GetTimeOfDay 实现的。在大多数 Win32 平台上,它是使用 ftime 实现的。 Win32 系统通常无法通过此 API 实现微秒级分辨率。如果更高的分辨率对您的应用程序至关重要,请测试您的平台以查看达到的分辨率。

    ftime 根本不提供微秒分辨率。参数可能包含单词microsecond,但实现不提供该范围内的任何准确性。它的粒度在 ms 范围内。

    当您的操作需要更多时间(例如至少 20 毫秒以上)时,您会得到不同于零的东西。

    编辑:注意:从长远来看,Windows 的microsec_clock 实现应该尽可能使用GetSystemTimePreciseAsFileTime function(最低要求。Windows 8 桌面、Windows Server 2012 桌面)以达到微秒级分辨率。

    【讨论】:

    • 这仅仅意味着 boost::posix_time::microsec_clock 是一个谎言 :))
    • 你不能说这是谎言。让值携带微秒是有意义的,因为这些值确实携带微秒范围内的信息。但是粒度不在那个范围内。一个典型的场景是时钟和万分之156,250 100 ns。这是 15.625 毫秒,即 15 毫秒和 625 微秒。 但是时钟会提前这么多。它有这样的粒度。
    【解决方案2】:

    不幸的是,boost::posix_time::microsec_clock 的当前 Boost 实现不使用 QueryPerformanceCounter Win32 API,它使用 GetSystemTimeAsFileTime 而不是使用 GetSystemTime。但是系统时间分辨率是毫秒(甚至更糟)。

    【讨论】:

    • 它不能使用 QueryPerformanceCounter 因为没有办法将它与绝对的真实世界时间联系起来,这是 boost::date_time 库的目的。如果您只想以高精度测量某件事花费了多长时间,请使用 boost chrono(或现在的 std::chrono)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 2012-04-12
    相关资源
    最近更新 更多