实现一个C++软件计时器
XCounter.h
#include <Windows.h>
class XCounter
{
public:
XCounter(void);
~XCounter(void);
XCounter(const XCounter& _Right);
virtual XCounter& operator=(const XCounter& _Right);
public:
//开始计时
virtual void start(void);
//停止计时
virtual void stop(void);
//重置计数器
virtual void reset(void);
//获取从开始计时到停止计时的间隔时间
virtual LONGLONG nanoSecond(void); //纳秒
virtual int microSecond(void); //微秒
virtual int milliSecond(void); //毫秒
virtual double second(void); //秒
//设定/获取时长
virtual void setDuration(const int _Duration);
virtual const int& duration(void);
//剩余的时间(微秒数)
virtual int remainingTime(void);
public:
LARGE_INTEGER m_Frequency; //高精度计数器频率
LARGE_INTEGER m_CntStart; //开始计时之时高精度性能计数器的值
LARGE_INTEGER m_CntStop; //停止计时之时高精度性能计数器的值
public:
int m_Duration; //设定的时长,单位:微秒,最大值为35.78分钟 (2^32/2-1)/10^6/60
DWORD g_LastError;
};
XCounter.cpp
#include "XCounter.h"
XCounter::XCounter(void)
: m_Frequency(LARGE_INTEGER())
, m_CntStart(LARGE_INTEGER())
, m_CntStop(LARGE_INTEGER())
, m_Duration(0)
{
//获取高精度计数器频率, 如:3328129Hz, 300纳秒
QueryPerformanceFrequency(&m_Frequency);
m_CntStart.QuadPart = 0;
m_CntStop.QuadPart = 0;
}
XCounter::~XCounter(void)
{
}
XCounter::XCounter(const XCounter& _Right)
: m_Frequency(_Right.m_Frequency)
, m_CntStart(_Right.m_CntStart)
, m_CntStop(_Right.m_CntStop)
, m_Duration(_Right.m_Duration)
{
}
XCounter& XCounter::operator=(const XCounter& _Right)
{
if (this != &_Right)
{
m_Frequency = (_Right.m_Frequency);
m_CntStart = (_Right.m_CntStart);
m_CntStop = (_Right.m_CntStop);
m_Duration = (_Right.m_Duration);
}
return (*this);
}
void XCounter::start(void)
{
if (!QueryPerformanceCounter(&m_CntStart))
{
g_LastError = GetLastError();
m_CntStart.QuadPart = 0;
}
}
void XCounter::stop(void)
{
if (!QueryPerformanceCounter(&m_CntStop))
{
g_LastError = GetLastError();
m_CntStop.QuadPart = 0;
}
}
void XCounter::reset(void)
{
m_CntStart.QuadPart = 0;
m_CntStop.QuadPart = 0;
}
//获取从开始计时到停止计时的间隔时间
//纳秒
LONGLONG XCounter::nanoSecond(void)
{
if (g_LastError)
return -1;
return (((m_CntStop.QuadPart - m_CntStart.QuadPart) * 1000 * 1000 * 1000) / m_Frequency.QuadPart/*Hz*/);
}
//微秒
int XCounter::microSecond(void)
{
//return (int)(nanoSecond() / 1000);
return (int)(((m_CntStop.QuadPart - m_CntStart.QuadPart) * 1000 * 1000) / m_Frequency.QuadPart/*Hz*/);
}
//毫秒
int XCounter::milliSecond(void)
{
//return (int)(nanoSecond() / (1000 * 1000));
return (int)(((m_CntStop.QuadPart - m_CntStart.QuadPart) * 1000) / m_Frequency.QuadPart/*Hz*/);
}
//秒
double XCounter::second(void)
{
//return (double)nanoSecond() / (1000.0 * 1000.0 * 1000.0);
return ((double)((m_CntStop.QuadPart - m_CntStart.QuadPart)) / m_Frequency.QuadPart/*Hz*/);
}
//设定/获取时长
void XCounter::setDuration(const int _Duration)
{
m_Duration = _Duration;
}
const int& XCounter::duration(void)
{
return m_Duration;
}
//剩余的时间(微秒数)
int XCounter::remainingTime(void)
{
if (g_LastError)
return -1;
int remaining = m_Duration - (int)(nanoSecond() / 1000);
if (remaining < 0)
return 0;
return remaining;
}
main.cpp
#include <iostream>
#include "XCounter.h"
int main()
{
XCounter cnt;
//std::cout << "开始计时!" << std::endl;
cnt.start();
Sleep(3000);
cnt.stop();
//std::cout << "计时结束!" << std::endl;
std::cout << "时间间隔:" << cnt.milliSecond() << std::endl;
std::cout << "frequency:" << cnt.m_Frequency.QuadPart << std::endl;
return 0;
}
输出结果
时间间隔:3001
frequency:10000000
其中用到的微软函数:
QueryPerformanceCounter
:检索性能计数器的当前值,这是一个高分辨率 (<1us) 时间戳,可用于时间间隔测量。
BOOL QueryPerformanceCounter(
[out] LARGE_INTEGER *lpPerformanceCount
);
传入的参数:指向接收当前性能计数器值的变量的指针,以计数为单位。
返回值:如果函数成功,则返回值非零。如果函数失败,则返回值为零。 要获取扩展错误信息,请调用 GetLastError
。 在运行 Windows XP
或更高版本的系统上,该函数将始终成功,因此永远不会返回零。
GetLastError
:检索调用线程的最后一个错误代码值。 最后一个错误代码是在每个线程的基础上维护的。 多个线程不会覆盖彼此的最后一个错误代码。
_Post_equals_last_error_ DWORD GetLastError();
OpenCV的计时器
#include <iostream>
#include <opencv2/core.hpp>
#include <windows.h>
int main()
{
double start = cv::getTickCount();
Sleep(3000);
double end = cv::getTickCount();
std::cout << "时间间隔:" << (end - start) * 1000/cv::getTickFrequency() << std::endl;
std::cout << "frequency:" << cv::getTickFrequency() << std::endl;
return 0;
}
输出结果
时间间隔:3011.39
frequency:1e+07
可见,频率是一样的,但计时精度有差距。
C++自带定时器
#include <time.h>
#include <iostream>
#include <windows.h>
int main()
{
clock_t start, end;
start = clock();
Sleep(3000);
end = clock();
std::cout << "时间间隔:" << (end - start) * 1000 / CLOCKS_PER_SEC << std::endl;
std::cout << "frequency:" << CLOCKS_PER_SEC << std::endl;
return 0;
}
输出结果
时间间隔:3012
frequency:1000
该计时器频率更小,计时精度更差。