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)。如果需要us级别的计时精度,Linux系统可以使用库函数:gettimeofday()。
注:
本文参照博客:https://www.cnblogs.com/hbccdf/p/microsecond_performance_statistics.html
推荐阅读
-
操作系统: 二级目录文件系统的实现(c/c++语言)
-
Window系统下C/C++程序毫秒级和微秒级执行时间获取方法
-
C++微秒级计时器实现
-
【C#源码】微秒级延迟实现方法分享
-
高精度/微秒级线程的实现
-
HAL库中同时实现微秒级us以及毫秒级ms延时
-
C++ STL中的map用红黑树实现,搜索效率是O(lgN),为什么不像python一样用散列表从而获得常数级搜索效率呢?
-
Python功能点实现:函数级/代码块级计时器
-
操作系统: 二级目录文件系统的实现(c/c++语言)
-
C++ STL中的map用红黑树实现,搜索效率是O(lgN),为什么不像python一样用散列表从而获得常数级搜索效率呢?