VS2013中的高分辨率时钟



我正在寻找具有高分辨率,高精度和相对较低性能影响的跨平台时钟(按重要性顺序)。

我尝试过:

//using namespace std::chrono;
//typedef std::chrono::high_resolution_clock Clock;
using namespace boost::chrono;
typedef boost::chrono::high_resolution_clock Clock;
auto now = Clock::now().time_since_epoch();
std::size_t secs = duration_cast<seconds>(now).count();
std::size_t nanos = duration_cast<nanoseconds>(now).count() % 1000000000;
std::time_t tp = (std::time_t) secs;
std::string mode;
char timestamp[] = "yyyymmdd HH:MM:SS";
char format[] = "%Y%m%d %H:%M:%S";
strftime(timestamp, 80, format, std::localtime(&tp)); // Takes 12 microseconds
std::string output = timestamp + "." + std::to_string(nanos);

经过一些试验和测试:原始的std :: chrono :: high_resolution_clock已输入System_Clock,并且精度约为1毫秒。BOOST :: CHRONO :: HIGH_RESOLUTION_CLOCK使用Windows上的QUERY_PERFORMANCE_COUNTER,并且具有高分辨率和精度。不幸的是,clock :: now()返回以来boot and now and()。time_since_epoch()不返回epoch时间(也返回自启动以来的时间)。

不介意使用警卫在不同平台上使用不同的解决方案(想要VS2013和Linux)。可能会存储现在并在单独/低优先级线程中进行处理。

是否存在跨平台,高分辨率,高精度,性能友好的计时器?

是boost :: chrono :: high_resolution_clock :: now()。time_since_epoch()按预期工作?自上一个时代以来,它没有给出时间。它只会给出一段时间以来。是否有一种方法可以将其转换为自时代以来的几秒钟。

我认为它最好的方法是实现新的时钟类型,该类型在C 11/14标准中建模Clock要求。

Windows功能GetSystemTimePreciseAsFileTime可以用作Windows时钟的基础。我相信,自Windows时期开始以来,此功能以100纳米秒的单位返回时间。如果对此我错了,只需更改period的定义以适合。

struct windows_highres_clock
{
    // implement Clock concept
    using rep = ULONGLONG;
    using period = std::ratio<1, 10000000>;
    using duration = std::chrono::duration<rep, period>;
    using time_point = std::chrono::time_point<windows_highres_clock, duration>;
    static constexpr const bool is_steady = true;
    static time_point now() noexcept {
        FILETIME ft = { 0, 0 };
        GetSystemTimePreciseAsFileTime(&ft);
        ULARGE_INTEGER stamp { { ft.dwLowDateTime, ft.dwHighDateTime } };
        return time_point { duration { stamp.QuadPart } };
    }
};

如果您想继续实现TrivalClock概念,则应该有效。只需在http://cppreference.com上按照说明

提供From_Time_T和TO_TIME_T成员功能将完成图片,并允许您使用此时钟进行计时和DateTime表示。

使用的示例:

windows_highres_clock clock;
auto t0 = clock.now();
sleep(1);
auto t1 = clock.now();
auto diff = t1 - t0;
auto ms = std::chrono::duration_cast<chrono::milliseconds>(diff);
cout << "waited for " << ms.count() << " millisecondsn";

示例输出:

waited for 1005 milliseconds

对于非Windows系统,System_Clock通常就足够了,但是您可以使用适当的本机定时机制编写类似的每个系统时钟。

fyi:

这是您可以用来检查时钟分辨率的便携式代码。类Any_Clock是一个可以容纳任何类似时钟的对象的多态容器。自从时代以来,它总是以微秒为单位返回其时间戳记。

// create some syntax to help specialise the any_clock
template<class Clock> struct of_type {};
// polymorphic clock container
struct any_clock
{
    template<class Clock>
    any_clock(of_type<Clock>)
    : _ptr { new model<Clock> {} }
    {}
    std::chrono::microseconds now() const {
        return _ptr->now();
    }
    using duration = std::chrono::microseconds;
private:
    struct concept {
        virtual ~concept() = default;
        virtual duration now() const noexcept = 0;
    };
    template<class Clock>
    struct model final : concept {
        duration now() const noexcept final {
            return std::chrono::duration_cast<std::chrono::microseconds>(Clock::now().time_since_epoch());
        }
    };
    unique_ptr<concept> _ptr;
};
int main(int argc, const char * argv[])
{
    any_clock clocks[] = {
         { of_type<windows_highres_clock>() },
         { of_type<std::chrono::high_resolution_clock>() },
         { of_type<std::chrono::system_clock>() }
    };
    static constexpr size_t nof_clocks = std::extent<decltype(clocks)>::value;
    any_clock::duration t0[nof_clocks];
    any_clock::duration t1[nof_clocks];
    for (size_t i = 0 ; i < nof_clocks ; ++i) {
        t0[i] = clocks[i].now();
    }
    sleep(1);
    for (size_t i = 0 ; i < nof_clocks ; ++i) {
        t1[i] = clocks[i].now();
    }
    for (size_t i = 0 ; i < nof_clocks ; ++i) {
        auto diff = t1[i] - t0[i];
        auto ms = std::chrono::duration_cast<chrono::microseconds>(diff);
        cout << "waited for " << ms.count() << " microsecondsn";
    }
    return 0;
}

最新更新