C语言精确计时方法
(2013-08-29 11:43:20)
标签:
c语言精确计时it |
1. QueryPerformanceFrequenc
精确获取时间:
QueryPerformanceFrequenc
类型:Win32API
原型:BOOL
QueryPerformanceFrequenc
作用:返回硬件支持的高精度计数器的频率。
返回值:非零,硬件支持高精度计数器;零,硬件不支持,读取失败。
QueryPerformanceFrequenc
供WIN9X使用的高精度定时器:QueryPerformanceFrequenc
函数的原形是:
BOOL
QueryPerformanceFrequenc
BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount);
数据类型LARGEINTEGER既可以是一个作为8字节长的整数,也可以是作为两个4字节长的整数的联合结构,其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typeef union _ LARGE_INTEGER
{
struct
{
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER;
在定时前应该先调用QueryPerformanceFrequenc
测试Sleep的精确时间:
#include
#include
void
{
system("Pause");
}
结果为
0.999982
1.000088
1.000200
等,所以Sleep的精度还是比较低的。
源地址:http://www.cppblog.com/deane/articles/113151.html
2.
static inline unsigned __int64 GetCycleCount()
{
unsigned int timehi, timelo;
__asm
{
rdtsc
mov timehi, edx;
mov timelo, eax;
}
return ((unsigned __int64)timehi << 32) + (unsigned __int64)timelo;
}
rdtsc这个指令是得到CPU自启动以后的运行周期,
在586以上的CPU上有这个指令将放回的数值,
高位返回到edx,
低位放回到eax,
可以用做随机数的种子可以在一段指令的前后调用rdtsc,计算运行这段指令的时间,
不过这个指令在超线程和多核CPU上用来计算时间不是很准确了。
3. 测试实例(运行环境:VS2012,Win7,i3,2.53GHz)
#include "stdio.h"
#include "windows.h"
static inline unsigned __int64 GetCycleCount()
{
unsigned int timehi, timelo;
__asm
{
rdtsc
mov timehi, edx;
mov timelo, eax;
}
return ((unsigned __int64)timehi << 32) + (unsigned __int64)timelo;
}
int _tmain(int argc, _TCHAR* argv[])
{
//PSO参数定义
float v_in=(float)0.45;
float x_in=(float)1.32;
float pbest=(float)0.68;
float gbest=(float)0.03;
float w=(float)0.7;
float c1=(float)2.0;
float c2=(float)2.0;
float r1=(float)0.35;
float r2=(float)0.72;
float v_out=(float)0.0;
//计时程序参数定义
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
double time;
printf("CPU Times:\n");
for(int i=0;i<10;i++)
{
QueryPerformanceFrequenc y(&nFreq);
QueryPerformanceCounter(&nBeginTime);
v_out=w*v_in+c1*r1*(pbest-x_in)+c2*r2*(gbest-x_in);
QueryPerformanceCounter(&nEndTime);
time=(double)1000000000.0*(nEndTime.QuadPart-nBeginTime.QuadPart)/(double)nFreq.QuadPart;
printf("%f:\t%f\n",v_out,time);
}
printf("CPU Cycles:\n");
for(int i=0;i<10;i++)
{
unsigned __int64 nBeginCycle = GetCycleCount();
v_out=w*v_in+c1*r1*(pbest-x_in)+c2*r2*(gbest-x_in);
unsigned __int64 nEndCycle = GetCycleCount();
unsigned __int64 nCycle = nEndCycle - nBeginCycle;
time=(double)nCycle/2.53;
printf("%f:\t%f\n",v_out,time);
}
return 0;
}
Result:
CPU Times:
-1.990600:405.210849
-1.990600:810.421699
-1.990600:405.210849
-1.990600:405.210849
-1.990600:405.210849
-1.990600:405.210849
-1.990600:405.210849
-1.990600:405.210849
-1.990600:405.210849
-1.990600:810.421699
CPU Cycles:
-1.990600:524.901186
-1.990600:447.430830
-1.990600:412.648221
-1.990600:409.486166
-1.990600:406.324111
-1.990600:422.134387
-1.990600:411.067194
-1.990600:411.067194
-1.990600:540.711462
-1.990600:493.280632
请按任意键继续. . .