C++: 急需一种求系统时间的方法,要求非常精确!!!!!!!!!
急!C++: 急需一种求系统时间的方法,要求非常精确!!!!!!!!!
我在网上找了很多种方法,但是都不太好,现在就有点恨我的CPU为什么要这么强了!
[解决办法]
#i nclude “stdio.h”
#i nclude “stdlib.h”
#i nclude “time.h”
int main( void )
{
long i = 10000000L;
clock_t start, finish;
double duration;
/* 测量一个事件持续的时间*/
printf( "Time to do %ld empty loops is ", i );
start = clock();
while( i-- )
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "%f seconds\n ", duration );
system( "pause ");
}
[解决办法]
呵呵,那你先用这个吧
#include "mmsystem.h "
#pragma comment(lib, "winmm.lib ")
int main()
{
DWORD s = 0;
DWORD d = 0;
s = timeGetTime();
// 第一个算法的代码
d = timeGetTime();
cout < < "第一个算法消耗的时间 : " < <d - s < < " 毫秒 " < <endl;
s = timeGetTime();
// 第二个算法的代码
d = timeGetTime();
cout < < "第二个算法消耗的时间 : " < <d - s < < " 毫秒 " < <endl;
return 0;
}
[解决办法]
我想测量一个算法的执行时间,用于同类算法的比较。不管它是什么时间,只要够精确就行了
====>
那这个最准确了, 它给出的是时钟周期.
#include <iostream>
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 main()
{
unsigned long num = 1000000;
unsigned __int64 start = GetCycleCount();
for (unsigned long i=0; i < num; ++i) {
double k = i+i;
}
unsigned __int64 end = GetCycleCount();
using namespace std;
cout < < "CPU cycles ellapsed for the long operation: " < <(end-start) < <endl;
}
[解决办法]
lightnut() 兄的这段代码复杂了...
inline unsigned __int64 GetCycleCount()
{
unsigned int timehi, timelo;
__asm
{
rdtsc
mov timehi, edx;
mov timelo, eax;
}
return ((unsigned __int64)timehi < < 32) + (unsigned __int64)timelo;
}
事实上,X86平台上,函数返回64位数据就是用的eax edx,你只要ret就可以了
[解决办法]
计算算法的CPU运行时间
一般有这么几个函数可以使用:
<time.h> 中的std的clock() 可以精确到1ms
<windows.h> 中的win下常用的GetTickCount可以精确到18-20ms
当然这些都不是C或是C++标准支持的。
我们先来看看clock()的用法:
#include <time.h>
#include <stdio.h>
int main()
{
time_t t;//一定要这个类型
long i;
t = clock();
for (i = 0; i < 1024 * 32768; ++i) ;//做些耗时的事情,可能就是你的算法
printf( "time consumed: %d ms ", clock() - t);//这样输出的就是耗时的毫秒数了
return 0;
}
GetTickCount()用法类似。
现在我们来介绍一个精度更加高的方法,直接读取CPU开机以来执行的机器周期数。
我们要用到一条汇编指令:RDTSC (就是ReaD TimeStamp Count) 其精度可以达到ns级别。(准确地说精度是1/你的CPU的时钟频率,这也是极限)
long hStart, lStart, hEnd, lEnd;
//分别代表开始的高位和低位以及结束的高位和低位,由于NS精度实在太高,所以数值会很大,1个32位的变量无法存储,需要两个32位变量
long hCnt, lCnt;//差值的高位和低位
__asm //内嵌汇编的语法可能不同编译器有些不同
{
RDTSC
mov hStart, edx
mov lStart, eax
}
//此处放上耗时的代码
__asm
{
RDTSC
mov hEnd, edx
mov lEnd, eax
//获取两次计数器值得差
sub eax, lStart
cmp eax, 0
jg L1
neg eax
jmp L2
L1:mov lCnt, eax
L2:sub edx, hStart
mov hCnt, edx
}
unsigned long timer = (hCnt < <32) + lCnt;//得出最终结果,timer就是所得的差值(单位ns)
[解决办法]
http://www.vckbase.com/document/viewdoc/?id=1301
[Ref]
在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率, 然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经 历的精确时间。下列代码实现1ms的精确定时:
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;// 获得初始值
do
{
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
}while(dfTim <0.001);
其定时误差不超过1微秒,精度与CPU等机器配置有关。