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 
请按任意键继续. . .

加载中…