C++微秒级计时器实现

微秒计时思路

在Windows平台上,用来统计微秒级别耗时信息,需要用到两个Windows API:

BOOL WINAPI QueryPerformanceFrequency(
  _Out_  LARGE_INTEGER *lpFrequency
);

BOOL WINAPI QueryPerformanceCounter(
  _Out_  LARGE_INTEGER *lpPerformanceCount
);

QueryPerformanceFrequency用于获取性能计数的频率,每秒多少次,
QueryPerformanceCounter用于获取当前性能计数的值,

有了这两个API,我们就可以用来统计耗时了,思路如下:
在这里插入图片描述
那么如何得到最终的耗时呢,公式如下:

秒级耗时 = (结束性能计数值 - 开始性能计数值) / 性能计数频率

微秒耗时 = (结束性能计数值 - 开始性能计数值)* 1000000 / 性能计数频率

微秒计时实现

#include<windows.h>

LARGE_INTEGER freq_;
QueryPerformanceFrequency(&freq_);

LARGE_INTEGER begin_time;
LARGE_INTEGER end_time;
QueryPerformanceCounter(&begin_time);
Sleep(100);
QueryPerformanceCounter(&end_time);

double ns_time = (end_time.QuadPart - begin_time.QuadPart) * 1000000.0 / freq_.QuadPart;

此时,ns_time的精度为微秒

封装微秒计时的实现

虽然上面已经实现了微秒精度计时,但是由于每次调用API时,都要定义变量等,使用起来肯定会有很多重复或者类似的代码,那么为了避免这种情况,对此实现进行了封装,如下:

class stop_watch
{
public:
    stop_watch()
        : elapsed_(0)
    {
        QueryPerformanceFrequency(&freq_);
    }
    ~stop_watch(){}
public:
    void start()
    {
        QueryPerformanceCounter(&begin_time_);
    }
    void stop()
    {
        LARGE_INTEGER end_time;
        QueryPerformanceCounter(&end_time);
        elapsed_ += (end_time.QuadPart - begin_time_.QuadPart) * 1000000 / freq_.QuadPart;
    }
    void restart()
    {
        elapsed_ = 0;
        start();
    }
    //微秒
    double elapsed()
    {
        return static_cast<double>(elapsed_);
    }
    //毫秒
    double elapsed_ms()
    {
        return elapsed_ / 1000.0;
    }
    //秒
    double elapsed_second()
    {
        return elapsed_ / 1000000.0;
    }

private:
    LARGE_INTEGER freq_;
    LARGE_INTEGER begin_time_;
    long long elapsed_;
};

调用此封装类示例:

stop_watch watch;
watch.start();
Sleep(100);
watch.stop();
cout << watch.elapsed() << " ns" << endl;

类似于 C++利用 clock()函数进行计时的调用方法,但比clock()函数计时精度更高。

Clock()函数

clock()函数返回值为1毫秒,就是0.001秒
功 能: 返回处理器调用某个进程或函数所花费的时间。
用 法: clock_t clock(void);
说明:clock_t其实就是long,即长整形。该函数返回值是硬件滴答数,要换算成秒或者毫秒,需要除以CLK_TCK或者CLOCKS_PER_SEC。比如,在VC++6.0下,这两个量的值都是1000,这表示硬件滴答1000下是1秒,因此要计算一个进程的时间,用clock()除以1000即可。

 start = clock();
 QuickSort(d,NUM);
 stop = clock();
 duration = (double)(stop-start)/(CLOCKS_PER_SEC);

注意:本函数仅能返回ms级的计时精度(事实上能够达到的计时精度大致与操作系统的线程切换时间相当,在windows平台上,极限精度大致是15~16ms)。

注:
本文参照博客:https://www.cnblogs.com/hbccdf/p/microsecond_performance_statistics.html

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值