一、需求描述
C++在Windows下,通过使用QueryPerformanceCounter可以实现毫秒级的高精度计时
题主在使用过程中主要有两个方面:秒表(计算某段代码的执行时间)和计时器(相当于sleep,但精度更高)
二、实现代码
1、秒表:计算某段代码的执行时间
#include <iostream>
#include <stdio.h>
#include <windows.h>
using namespace std;
int main()
{
//初始化计时器
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime, nEndTime;
double time = 0;
QueryPerformanceFrequency(&nFreq);
//取开始执行时间
QueryPerformanceCounter(&nBeginTime);
//这里填写需要执行的代码
//取结束执行时间
QueryPerformanceCounter(&nEndTime);
//计算时间差
time = (double)(nEndTime.QuadPart - nBeginTime.QuadPart) * 1000 / (double)nFreq.QuadPart;
system("pause");
return 0;
}
2、计时器:sleep一段时间
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <thread>
using namespace std;
//设置时间间隔,单位:ms
const int nIntervalTime = 40;
int main()
{
//初始化计时器
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime, nEndTime;
double time = 0, Residual = 0, dThisTime = nIntervalTime;
QueryPerformanceFrequency(&nFreq);
while (true)
{
//取开始执行时间
QueryPerformanceCounter(&nBeginTime);
do
{
//取结束执行时间
QueryPerformanceCounter(&nEndTime);
//计算时间差
time = (double)(nEndTime.QuadPart - nBeginTime.QuadPart) * 1000 / (double)nFreq.QuadPart;
//通过线程的等待来降低循环次数,达到减少CPU占用的目的
if (time + 1 < nIntervalTime)
this_thread::sleep_for(chrono::milliseconds((int)(nIntervalTime - time - 1)));
} while (time < nIntervalTime);//当时间小于本次预计的时间时继续循环
//这里填写定时结束后需要执行的程序
}
system("pause");
return 0;
}
3、自适应计时器:sleep一段时间,根据代码执行时间,尽量保证代码固定频率执行(使用场景举例:某段代码需要以固定的时间间隔执行)
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <thread>
using namespace std;
//设置时间间隔,单位:ms
const int nIntervalTime = 40;
int main()
{
//初始化计时器
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime, nEndTime;
double time = 0, Residual = 0, dThisTime = nIntervalTime;
QueryPerformanceFrequency(&nFreq);
while (true)
{
//取开始执行时间
QueryPerformanceCounter(&nBeginTime);
//这里填写需要执行的代码
do
{
//取结束执行时间
QueryPerformanceCounter(&nEndTime);
//计算时间差
time = (double)(nEndTime.QuadPart - nBeginTime.QuadPart) * 1000 / (double)nFreq.QuadPart;
//通过线程的等待来降低循环次数,达到减少CPU占用的目的
if (time + 1 < dThisTime)
this_thread::sleep_for(chrono::milliseconds((int)(dThisTime - time - 1)));
} while (time < dThisTime);//当时间小于本次预计的时间时继续循环
//残余时间可能为正也可能为负
Residual = dThisTime - time;
//根据设置时间间隔和上一次执行的残余时间,计算下一次执行的时间
dThisTime = nIntervalTime + Residual;
}
system("pause");
return 0;
}