轉自:http://blog.csdn.net/fz_ywj/article/details/8109368
C語言中常用計時方法總結
1. time()
頭文件:time.h
函數原型:time_t time(time_t * timer)
功能:返回以格林尼治時間(GMT)為標准,從1970年1月1日00:00:00到現在的此時此刻所經過的秒數。
用time()函數結合其他函數(如:localtime、gmtime、asctime、ctime)可以獲得當前系統時間或是標准時間。
用difftime函數可以計算兩個time_t類型的時間的差值,可以用於計時。用difftime(t2,t1)要比t2-t1更准確,因為C標准中並沒有規定time_t的單位一定是秒,而difftime會根據機器進行轉換,更可靠。
用法:
- time_t start,end;
- start =time(NULL);//or time(&start);
- //…calculating…
- end =time(NULL);
- printf("time=%d\n",difftime(end,start));
2. clock()
頭文件:time.h
函數原型:clock_t clock(void);
功能:該函數返回值是硬件滴答數,要換算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC。比如,在VC++6.0下,這兩個量的值都是1000。
用法:
- clock_t start,end;
- start = clock();
- //…calculating…
- end = clock();
- printf("time=%f\n",(double)end-start)/CLK_TCK);
3. timeGetTime()
WIN32API
頭文件:Mmsystem.h 引用庫: Winmm.lib
函數原型:DWORD timeGetTime(VOID);
功能:返回系統時間,以毫秒為單位。系統時間是從系統啟動到調用函數時所經過的毫秒數。注意,這個值是32位的,會在0到2^32之間循環,約49.71天。
用法:
- DWORDstart,end;
- start= timeGetTime();
- //…calculating…
- end= timeGetTime();
- printf("time=%d\n",end-start);
4. GetTickCount()
WIN32API
頭文件:windows.h
函數原型:DWORD WINAPI GetTickCount(void);
功能:返回自設備啟動后的毫秒數(不含系統暫停時間)。
用法:
- DWORDstart,end;
- start= GetTickCount();
- //…calculating…
- end= GetTickCount();
- printf("time=%d\n",end-start);
5. QueryPerformanceCounter()、QueryPerformanceFrequency()
WIN32API
頭文件:windows.h
函數原型:BOOLQueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
BOOLQueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
功能:前者獲得的是CPU從開機以來執行的時鍾周期數。后者用於獲得你的機器一秒鍾執行多少次,就是你的時鍾周期。
補充:LARGE_INTEGER既可以是一個8字節長的整型數,也可以是兩個4字節長的整型數的聯合結構, 其具體用法根據編譯器是否支持64位而定:
- typedef union_LARGE_INTEGER
- {
- struct
- {
- DWORD LowPart ;
- LONG HighPart;
- };
- LONGLONG QuadPart ;
- }LARGE_INTEGER;
用法:
在進行定時之前,先調用QueryPerformanceFrequency()函數獲得機器內部定時器的時鍾頻率,然后在需要嚴格定時的事件發生之前和發生之后分別調用QueryPerformanceCounter()函數,利用兩次獲得的計數之差及時鍾頻率,計算出事件經歷的精確時間。
- LARGE_INTEGER num;
- longlong start,end,freq;
- QueryPerformanceFrequency(&num);
- freq=num.QuadPart;
- QueryPerformanceCounter(&num);
- start= num.QuadPart;
- //…calculating…
- QueryPerformanceCounter(&num);
- end= num.QuadPart;
- printf("time=%d\n",(end-start)*1000/freq);
6. gettimeofday()
Linux C函數。
頭文件:sys/time.h
函數原型:int gettimeofday(struct timeval *tv,struct timezone *tz);
說明:其參數tv是保存獲取時間結果的結構體,參數tz用於保存時區結果(若不使用則傳入NULL即可)。
timeval的定義為:
- struct timeval {
- long tv_sec; // 秒數
- long tv_usec; //微秒數
- }
用法:
- struct timeval start,end;
- gettimeofday(&start, NULL );
- //…calculating…
- gettimeofday(&end, NULL );
- long timeuse =1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec;
- printf("time=%f\n",timeuse /1000000.0);
7. RDTSC - 讀取時間標簽計數器
X86架構CPU匯編指令。
操作碼:0F 31 指令:RDTSC
功能:將時間標簽計數器讀入 EDX:EAX寄存器中。
說明:在Pentium以上的CPU中,提供了一條機器指令RDTSC來讀取這個時間戳的數字,並將其保存在EDX:EAX寄存器對中。由於EDX:EAX寄存器對恰好是Win32平台下C++語言保存函數返回值的寄存器,所以我們可以把這條指令看成是一個普通的函數調用:
- inline unsigned long longGetCycleCount()
- {
- __asm RDTSC
- }
- inline unsigned long long GetCycleCount()
- {
- __asm _emit 0x0F
- __asm _emit 0x31
- }
- #ifdef WIN32
- #include <windows.h>
- #else
- #include <sys/unistd.h>
- #endif
- inline unsigned long long GetNTime()
- {
- __asm("RDTSC");
- }
- static double hz=0.0;
- void init_timer()
- {
- longlong t1=GetNTime();
- #ifdef WIN32
- Sleep(1000);
- #else
- sleep(1);
- #endif
- longlong t=GetNTime()-t1;
- hz=(double)t/1000000000;
- printf("hz=%fGhz\n",hz);
- }
- long long u_timer(long long *t,int mode)
- {
- if(hz<0.001)
- init_timer();
- if(!mode)
- {
- *t=GetNTime();
- return0;
- }
- longlong t1=GetNTime()-*t;
- t1/=hz;
- longlong ns=t1%1000;
- longlong us=(t1/1000)%1000;
- longlong ms=(t1/1000000)%1000;
- longlong s=t1/1000000000;
- printf("time=");
- if(s!=0)
- printf("%llds",s);
- if(ms!=0)
- printf("%lldms",ms);
- if(us!=0)
- printf("%lldus",us);
- if(ns!=0)
- printf("%lldns",ns);
- printf("\n");
- *t=GetNTime();
- returnt1;
- }