Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;跨平台高分辨率定时器 我想在C++中实现一个简单的计时器机制。该代码应该在Windows和Linux中工作。分辨率应尽可能精确(至少毫秒精度)。这将用于简单地跟踪时间的流逝,而不是实现任何类型的事件驱动设计。什么是实现这一目标的最好工具? < p> C++库问题的第一个答案一般是Booo:这是你想要的吗?可能不会,但这只是一个开始_C++_Cross Platform_Timer - Fatal编程技术网

C++;跨平台高分辨率定时器 我想在C++中实现一个简单的计时器机制。该代码应该在Windows和Linux中工作。分辨率应尽可能精确(至少毫秒精度)。这将用于简单地跟踪时间的流逝,而不是实现任何类型的事件驱动设计。什么是实现这一目标的最好工具? < p> C++库问题的第一个答案一般是Booo:这是你想要的吗?可能不会,但这只是一个开始

C++;跨平台高分辨率定时器 我想在C++中实现一个简单的计时器机制。该代码应该在Windows和Linux中工作。分辨率应尽可能精确(至少毫秒精度)。这将用于简单地跟踪时间的流逝,而不是实现任何类型的事件驱动设计。什么是实现这一目标的最好工具? < p> C++库问题的第一个答案一般是Booo:这是你想要的吗?可能不会,但这只是一个开始,c++,cross-platform,timer,C++,Cross Platform,Timer,问题是,您希望便携和计时器功能在操作系统中不是通用的。开源库在windows和linux平台上都提供了一个非常好的解决方案。如果您想自己实现它,只需查看它们的来源。我不确定您的要求,如果您想计算时间间隔,请参阅下面的线程 对于C++03: 可能会工作,但它取决于C函数时钟,因此可能没有足够好的分辨率 Boost.Date\u时间包括以前在堆栈溢出上建议使用的时间。请参见其在microsec_-clock::local_-time和microsec_-clock::universal_-time上

问题是,您希望便携和计时器功能在操作系统中不是通用的。

开源库在windows和linux平台上都提供了一个非常好的解决方案。如果您想自己实现它,只需查看它们的来源。

我不确定您的要求,如果您想计算时间间隔,请参阅下面的线程


对于C++03

可能会工作,但它取决于C函数
时钟
,因此可能没有足够好的分辨率

Boost.Date\u时间包括以前在堆栈溢出上建议使用的时间。请参见其在
microsec_-clock::local_-time
microsec_-clock::universal_-time
上的文档,但请注意其警告:“Win32系统通常无法通过此API实现微秒分辨率。”

除其他事项外,还提供了一个围绕OS特定API的瘦跨平台(Windows和Linux/UNIX)C++包装器。Its有几个类可以满足您的需要。(要使其跨平台,请选择一个类,如

performance\u counter
,该类同时存在于
winstl
unixstl
名称空间中,然后使用与您的平台匹配的名称空间。)

对于C++11及以上版本


std::chrono
库内置了此功能。有关详细信息,请参见@HowardHinnant。

ACE库还具有便携式高分辨率计时器。

用于高分辨率定时器的氧气:

我曾多次看到它作为封闭源代码的内部解决方案实施。。。。它们都求助于
#ifdef
解决方案,一方面使用原生Windows高分辨率计时器,另一方面使用
struct timeval
(请参见
man timeradd
)的Linux内核计时器


您可以对其进行抽象,一些开源项目已经做到了这一点——我最后一次看的是,但肯定还有更多的项目。

为此,我强烈推荐boost::posix_时间库。它支持分辨率低至微秒的计时器,我相信它有一个,包括一组计时器类,其中一些适用于UNIX和Windows。

提供了几种计时器类型,具有一致的接口,因此您可以即插即用。其中包括低成本但低分辨率的定时器,以及高分辨率但高成本的定时器。还有一些用于测量线程前时间和每个进程的时间,以及所有用于测量运行时间的时间

这是几年前的一篇详尽的文章,虽然它只涵盖了Windows,那些在WinSL子项目中定义的。STLSoft还在UNIXSTL子项目中提供UNIX计时器,您可以使用“PlatformSTL”计时器,其中包括UNIX或Windows计时器(视情况而定),如下所示:

#include <platformstl/performance/performance_counter.hpp>
#include <iostream>

int main()
{
    platformstl::performance_counter c;

    c.start();
    for(int i = 0; i < 1000000000; ++i);
    c.stop();

    std::cout << "time (s): " << c.get_seconds() << std::endl;
    std::cout << "time (ms): " << c.get_milliseconds() << std::endl;
    std::cout << "time (us): " << c.get_microseconds() << std::endl;
}
#包括
#包括
int main()
{
平台stl::性能计数器c;
c、 start();
对于(int i=0;i<100000000;++i);
c、 停止();

std::cout更新了一个旧问题的答案:

在C++11中,您可以通过以下方式移植到最高分辨率的计时器:

#include <iostream>
#include <chrono>
#include "chrono_io"

int main()
{
    typedef std::chrono::high_resolution_clock Clock;
    auto t1 = Clock::now();
    auto t2 = Clock::now();
    std::cout << t2-t1 << '\n';
}
“chrono_io”是一个扩展,用于缓解这些新类型的I/O问题,并免费提供

boost中还有一个
的实现(可能仍然在主干的顶端,不确定它是否已经发布)

更新

这是为了回应Ben在下面的评论,即VS11中对
std::chrono::high_resolution_clock
的后续调用需要几毫秒。下面是一个与
兼容的解决方法。但是它只在英特尔硬件上工作,您需要深入到内联汇编(执行此操作的语法因编译器而异),您必须将机器的时钟速度硬连线到时钟中:

#include <chrono>

struct clock
{
    typedef unsigned long long                 rep;
    typedef std::ratio<1, 2800000000>          period; // My machine is 2.8 GHz
    typedef std::chrono::duration<rep, period> duration;
    typedef std::chrono::time_point<clock>     time_point;
    static const bool is_steady =              true;

    static time_point now() noexcept
    {
        unsigned lo, hi;
        asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
        return time_point(duration(static_cast<rep>(hi) << 32 | lo));
    }

private:

    static
    unsigned
    get_clock_speed()
    {
        int mib[] = {CTL_HW, HW_CPU_FREQ};
        const std::size_t namelen = sizeof(mib)/sizeof(mib[0]);
        unsigned freq;
        size_t freq_len = sizeof(freq);
        if (sysctl(mib, namelen, &freq, &freq_len, nullptr, 0) != 0)
            return 0;
        return freq;
    }

    static
    bool
    check_invariants()
    {
        static_assert(1 == period::num, "period must be 1/freq");
        assert(get_clock_speed() == period::den);
        static_assert(std::is_same<rep, duration::rep>::value,
                      "rep and duration::rep must be the same type");
        static_assert(std::is_same<period, duration::period>::value,
                      "period and duration::period must be the same type");
        static_assert(std::is_same<duration, time_point::duration>::value,
                      "duration and time_point::duration must be the same type");
        return true;
    }

    static const bool invariants;
};

const bool clock::invariants = clock::check_invariants();
#包括
结构时钟
{
typedef无符号长代表;
typedef std::比率周期;//我的机器是2.8 GHz
typedef std::chrono::duration duration;
typedef std::chrono::time_point time_point;
静态常数布尔值为稳定=真;
静态时间点now()无例外
{
未签名的lo,hi;
asm易失性(“rdtsc”:“=a”(lo),“=d”(hi));

返回时间点(duration)(static)\u cast(hi)如果在项目中使用Qt框架,最好的解决方案可能是使用QeReleasedTimer。

有一个优秀的跨平台高分辨率计时器。但是,如果您需要亚毫秒精度,我编写了一个非常小的跨平台计时器库。
它与C++ 03和C++ 11的版本相比较,在C++的高级版本中兼容。

在这里的聚会上,但是我在一个不能升级到C++ 11的遗留代码库中工作。我们团队中没有人是非常熟练的C++,所以增加像STL这样的库是困难的(除了其他人提出的关于部署问题的潜在关注)。。我真的需要一个非常简单的跨平台计时器,它可以独立工作,而不需要任何超出基本标准系统库的东西。以下是我的发现:

在此处重新发布整个源代码,以便在站点死亡时不会丢失:

    //////////////////////////////////////////////////////////////////////////////
// Timer.cpp
// =========
// High Resolution Timer.
// This timer is able to measure the elapsed time with 1 micro-second accuracy
// in both Windows, Linux and Unix system 
//
//  AUTHOR: Song Ho Ahn (song.ahn@gmail.com) - http://www.songho.ca/misc/timer/timer.html
// CREATED: 2003-01-13
// UPDATED: 2017-03-30
//
// Copyright (c) 2003 Song Ho Ahn
//////////////////////////////////////////////////////////////////////////////

#include "Timer.h"
#include <stdlib.h>

///////////////////////////////////////////////////////////////////////////////
// constructor
///////////////////////////////////////////////////////////////////////////////
Timer::Timer()
{
#if defined(WIN32) || defined(_WIN32)
    QueryPerformanceFrequency(&frequency);
    startCount.QuadPart = 0;
    endCount.QuadPart = 0;
#else
    startCount.tv_sec = startCount.tv_usec = 0;
    endCount.tv_sec = endCount.tv_usec = 0;
#endif

    stopped = 0;
    startTimeInMicroSec = 0;
    endTimeInMicroSec = 0;
}



///////////////////////////////////////////////////////////////////////////////
// distructor
///////////////////////////////////////////////////////////////////////////////
Timer::~Timer()
{
}



///////////////////////////////////////////////////////////////////////////////
// start timer.
// startCount will be set at this point.
///////////////////////////////////////////////////////////////////////////////
void Timer::start()
{
    stopped = 0; // reset stop flag
#if defined(WIN32) || defined(_WIN32)
    QueryPerformanceCounter(&startCount);
#else
    gettimeofday(&startCount, NULL);
#endif
}



///////////////////////////////////////////////////////////////////////////////
// stop the timer.
// endCount will be set at this point.
///////////////////////////////////////////////////////////////////////////////
void Timer::stop()
{
    stopped = 1; // set timer stopped flag

#if defined(WIN32) || defined(_WIN32)
    QueryPerformanceCounter(&endCount);
#else
    gettimeofday(&endCount, NULL);
#endif
}



///////////////////////////////////////////////////////////////////////////////
// compute elapsed time in micro-second resolution.
// other getElapsedTime will call this first, then convert to correspond resolution.
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInMicroSec()
{
#if defined(WIN32) || defined(_WIN32)
    if(!stopped)
        QueryPerformanceCounter(&endCount);

    startTimeInMicroSec = startCount.QuadPart * (1000000.0 / frequency.QuadPart);
    endTimeInMicroSec = endCount.QuadPart * (1000000.0 / frequency.QuadPart);
#else
    if(!stopped)
        gettimeofday(&endCount, NULL);

    startTimeInMicroSec = (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
    endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
#endif

    return endTimeInMicroSec - startTimeInMicroSec;
}



///////////////////////////////////////////////////////////////////////////////
// divide elapsedTimeInMicroSec by 1000
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInMilliSec()
{
    return this->getElapsedTimeInMicroSec() * 0.001;
}



///////////////////////////////////////////////////////////////////////////////
// divide elapsedTimeInMicroSec by 1000000
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInSec()
{
    return this->getElapsedTimeInMicroSec() * 0.000001;
}



///////////////////////////////////////////////////////////////////////////////
// same as getElapsedTimeInSec()
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTime()
{
    return this->getElapsedTimeInSec();
}
//////////////////////////////////////////////////////////////////////////////
//Timer.cpp
// =========
//高分辨率定时器。
//该计时器能够以1微秒的精度测量经过的时间
//在Windows、Linux和Unix系统中
//
//作者:宋浩安(宋。ahn@gmail.com) - http://www.songho.ca/misc/timer/timer.html
//创建日期:2003-01-13
//更新日期:2017-0
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
auto t0 = clock::now();
auto t1 = clock::now();
nanoseconds ns = duration_cast<nanoseconds>(t1-t0);
    //////////////////////////////////////////////////////////////////////////////
// Timer.cpp
// =========
// High Resolution Timer.
// This timer is able to measure the elapsed time with 1 micro-second accuracy
// in both Windows, Linux and Unix system 
//
//  AUTHOR: Song Ho Ahn (song.ahn@gmail.com) - http://www.songho.ca/misc/timer/timer.html
// CREATED: 2003-01-13
// UPDATED: 2017-03-30
//
// Copyright (c) 2003 Song Ho Ahn
//////////////////////////////////////////////////////////////////////////////

#include "Timer.h"
#include <stdlib.h>

///////////////////////////////////////////////////////////////////////////////
// constructor
///////////////////////////////////////////////////////////////////////////////
Timer::Timer()
{
#if defined(WIN32) || defined(_WIN32)
    QueryPerformanceFrequency(&frequency);
    startCount.QuadPart = 0;
    endCount.QuadPart = 0;
#else
    startCount.tv_sec = startCount.tv_usec = 0;
    endCount.tv_sec = endCount.tv_usec = 0;
#endif

    stopped = 0;
    startTimeInMicroSec = 0;
    endTimeInMicroSec = 0;
}



///////////////////////////////////////////////////////////////////////////////
// distructor
///////////////////////////////////////////////////////////////////////////////
Timer::~Timer()
{
}



///////////////////////////////////////////////////////////////////////////////
// start timer.
// startCount will be set at this point.
///////////////////////////////////////////////////////////////////////////////
void Timer::start()
{
    stopped = 0; // reset stop flag
#if defined(WIN32) || defined(_WIN32)
    QueryPerformanceCounter(&startCount);
#else
    gettimeofday(&startCount, NULL);
#endif
}



///////////////////////////////////////////////////////////////////////////////
// stop the timer.
// endCount will be set at this point.
///////////////////////////////////////////////////////////////////////////////
void Timer::stop()
{
    stopped = 1; // set timer stopped flag

#if defined(WIN32) || defined(_WIN32)
    QueryPerformanceCounter(&endCount);
#else
    gettimeofday(&endCount, NULL);
#endif
}



///////////////////////////////////////////////////////////////////////////////
// compute elapsed time in micro-second resolution.
// other getElapsedTime will call this first, then convert to correspond resolution.
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInMicroSec()
{
#if defined(WIN32) || defined(_WIN32)
    if(!stopped)
        QueryPerformanceCounter(&endCount);

    startTimeInMicroSec = startCount.QuadPart * (1000000.0 / frequency.QuadPart);
    endTimeInMicroSec = endCount.QuadPart * (1000000.0 / frequency.QuadPart);
#else
    if(!stopped)
        gettimeofday(&endCount, NULL);

    startTimeInMicroSec = (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
    endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
#endif

    return endTimeInMicroSec - startTimeInMicroSec;
}



///////////////////////////////////////////////////////////////////////////////
// divide elapsedTimeInMicroSec by 1000
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInMilliSec()
{
    return this->getElapsedTimeInMicroSec() * 0.001;
}



///////////////////////////////////////////////////////////////////////////////
// divide elapsedTimeInMicroSec by 1000000
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInSec()
{
    return this->getElapsedTimeInMicroSec() * 0.000001;
}



///////////////////////////////////////////////////////////////////////////////
// same as getElapsedTimeInSec()
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTime()
{
    return this->getElapsedTimeInSec();
}
//////////////////////////////////////////////////////////////////////////////
// Timer.h
// =======
// High Resolution Timer.
// This timer is able to measure the elapsed time with 1 micro-second accuracy
// in both Windows, Linux and Unix system 
//
//  AUTHOR: Song Ho Ahn (song.ahn@gmail.com) - http://www.songho.ca/misc/timer/timer.html
// CREATED: 2003-01-13
// UPDATED: 2017-03-30
//
// Copyright (c) 2003 Song Ho Ahn
//////////////////////////////////////////////////////////////////////////////

#ifndef TIMER_H_DEF
#define TIMER_H_DEF

#if defined(WIN32) || defined(_WIN32)   // Windows system specific
#include <windows.h>
#else          // Unix based system specific
#include <sys/time.h>
#endif


class Timer
{
public:
    Timer();                                    // default constructor
    ~Timer();                                   // default destructor

    void   start();                             // start timer
    void   stop();                              // stop the timer
    double getElapsedTime();                    // get elapsed time in second
    double getElapsedTimeInSec();               // get elapsed time in second (same as getElapsedTime)
    double getElapsedTimeInMilliSec();          // get elapsed time in milli-second
    double getElapsedTimeInMicroSec();          // get elapsed time in micro-second


protected:


private:
    double startTimeInMicroSec;                 // starting time in micro-second
    double endTimeInMicroSec;                   // ending time in micro-second
    int    stopped;                             // stop flag 
#if defined(WIN32) || defined(_WIN32)
    LARGE_INTEGER frequency;                    // ticks per second
    LARGE_INTEGER startCount;                   //
    LARGE_INTEGER endCount;                     //
#else
    timeval startCount;                         //
    timeval endCount;                           //
#endif
};

#endif // TIMER_H_DEF
/* ----------------------------------------------------------------------- */
/*
Easy embeddable cross-platform high resolution timer function. For each 
platform we select the high resolution timer. You can call the 'ns()' 
function in your file after embedding this. 
*/
#include <stdint.h>
#if defined(__linux)
#  define HAVE_POSIX_TIMER
#  include <time.h>
#  ifdef CLOCK_MONOTONIC
#     define CLOCKID CLOCK_MONOTONIC
#  else
#     define CLOCKID CLOCK_REALTIME
#  endif
#elif defined(__APPLE__)
#  define HAVE_MACH_TIMER
#  include <mach/mach_time.h>
#elif defined(_WIN32)
#  define WIN32_LEAN_AND_MEAN
#  include <windows.h>
#endif
static uint64_t ns() {
static uint64_t is_init = 0;
#if defined(__APPLE__)
    static mach_timebase_info_data_t info;
    if (0 == is_init) {
        mach_timebase_info(&info);
        is_init = 1;
    }
    uint64_t now;
    now = mach_absolute_time();
    now *= info.numer;
    now /= info.denom;
    return now;
#elif defined(__linux)
    static struct timespec linux_rate;
    if (0 == is_init) {
        clock_getres(CLOCKID, &linux_rate);
        is_init = 1;
    }
    uint64_t now;
    struct timespec spec;
    clock_gettime(CLOCKID, &spec);
    now = spec.tv_sec * 1.0e9 + spec.tv_nsec;
    return now;
#elif defined(_WIN32)
    static LARGE_INTEGER win_frequency;
    if (0 == is_init) {
        QueryPerformanceFrequency(&win_frequency);
        is_init = 1;
    }
    LARGE_INTEGER now;
    QueryPerformanceCounter(&now);
    return (uint64_t) ((1e9 * now.QuadPart)  / win_frequency.QuadPart);
#endif
}
/* ----------------------------------------------------------------------- */-------------------------------- */