轉載 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));
time_t start,end;
start =time(NULL);//or time(&start);
//…calculating…
end =time(NULL);
printf("time=%d\n",difftime(end,start));
總結:C標準庫中的函數,可移植性最好,性能也很穩定,但精度太低,只能精確到秒,對於一般的事件計時還算夠用,而對運算時間的計時就明顯不夠用了。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);
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);
DWORDstart,end;
start= timeGetTime();
//…calculating…
end= timeGetTime();
printf("time=%d\n",end-start);
總結:該函數的時間精度是五毫秒或更大一些,這取決於機器的性能。可用timeBeginPeriod和timeEndPeriod函數提高timeGetTime函數的精度。如果使用了,連續調用timeGetTime函數,一系列返回值的差異由timeBeginPeriod和timeEndPeriod決定。4. GetTickCount()
WIN32API
頭文件:windows.h
函數原型:DWORD WINAPI GetTickCount(void);
功能:返回自設備啓動後的毫秒數(不含系統暫停時間)。
用法:
- DWORDstart,end;
- start= GetTickCount();
- //…calculating…
- end= GetTickCount();
- printf("time=%d\n",end-start);
DWORDstart,end;
start= GetTickCount();
//…calculating…
end= GetTickCount();
printf("time=%d\n",end-start);
總結:精確到毫秒。對於一般的實時控制,使用GetTickCount()函數就可以滿足精度要求。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;
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);
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);
總結:這種方法的定時誤差不超過1微秒,精度與CPU等機器配置有關,一般認爲精度爲透微秒級。在Windows平臺下進行高精度計時的時候可以考慮這種方法。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 {
long tv_sec; // 秒數
long tv_usec; //微秒數
}
可見該函數可用於在linux中獲得微秒精度的時間。用法:
- 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);
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);
總結:使用這種方式計時,精度可達微秒。經驗證,在arm+linux的環境下此函數仍可使用。推薦。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 longGetCycleCount()
{
__asm RDTSC
}
如果編譯器不允許直接用RDTSC的話,可以用_emit僞指令直接嵌入該指令的機器碼形式0X0F、0X31:- inline unsigned long long GetCycleCount()
- {
- __asm _emit 0x0F
- __asm _emit 0x31
- }
inline unsigned long long GetCycleCount()
{
__asm _emit 0x0F
__asm _emit 0x31
}
計算時還需要將得到的數字除以CPU的主頻(單位GHZ),就能得到納秒級的時間了。暫時我還沒找到好的獲得機器主頻的方法,Windows平臺下可以考慮用QueryPerformanceFrequency()函數,但這樣一來就沒辦法在Linux下使用此方法。後來我考慮配合sleep函數,獲取1秒中的機器週期數的方法來得到CPU主頻。如果哪位有更好的方法,還請多多請教。- #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;
- }
#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;
}
總結:這種方法精確到納秒,但缺點是非常短時間的計時會不穩定。最近因爲項目需要,我也找了一下ARM+Linux平臺上可以用的計時方法,後來選擇了gettimeofday()。不知道ARM+Linux平臺上有沒有類似RDTSC的這種指令。- 本文已收錄於以下專欄:
-
-
lqxandroid2012
2016-05-23 10:40 1樓 -
gettimeofday能在Linux 驅動中用嗎?
-
相關文章推薦
-
c語言中如何添加計時函數,統計程序執行的時間
這裏舉一個例子,行優先和列優先遍歷二維數組的程序執行時間比較,這裏需要調用 time.h 編譯環境爲vs2013#define M 10000000#define N 10short a[M][...- baidu_36856113
- 2016年12月09日 16:55
- 3958
-
C語言中的計時方法:time
在Linux中用C語言計時可以用很多方法。 1. 可用使用C語言庫自帶的clock()進行計時。如: #include #include using namespa...- DC_Neo
- 2012年09月14日 12:50
- 1786
-
一個普通程序員的內心獨白....躺槍!躺槍!
我,一個普普通通程序員,沒有過人的天賦,沒有超乎尋常的好運,該如何逆襲走上人生巔峯?
-
Delphi7高級應用開發隨書源碼
- 2003年04月30日 00:00
- 676KB
- 下載
-
C語言計時器的使用
1.如果是想使用秒級別的技術,可用使用C語言庫time.h>自帶的clock()進行計時。如: #include iostream> #include time.h> u...- darennet
- 2014年10月30日 09:01
- 821
-
C語言中常用計時方法總結
C語言中常用計時方法總結1. time()頭文件:time.h函數原型:time_t time(time_t * timer)功能:返回以格林尼治時間(GMT)爲標準,從1970年1月1...- shine_journey
- 2016年03月25日 11:05
- 1528
-
程序員跨越式成長指南
完成第一次跨越,你會成爲具有一技之長的開發者,月薪可能翻上幾番; 完成第二次跨越,你將成爲擁有局部優勢或行業優勢的專業人士,獲得個人內在價值的有效提升和外在收入的大幅躍遷……
-
C語言給函數計時
C/C++中的計時函數是clock(),而與其相關的數據類型是clock_t。在MSDN中,查得對clock函數定義如下:clock_t clock( void );這個函數返回從“開啓這個程序進程”...- leohxj
- 2010年06月29日 20:22
- 7624
-
C語言中對程序運行計時
使用time()函數。它在頭文件time.h中具體使用方法如下:time_t a,b;//time_t是表示時間的結構體,你可以在time.h中找到它的原型。a=time(NULL);//...- Bruce_imu
- 2012年10月10日 21:07
- 1127
-
C語言時間差計算函數clock() 與 time ()用法分析
在很多情況下,爲了評判某個算法,函數的優劣,特別是比較同一個功能的兩個函數的效率高低時,我們經常通過計算耗費時間作爲判斷標準。C語言中有兩個相關的函數用來計算時間差,分別是:time_t time(...- linpengbin
- 2015年02月03日 20:00
- 9924
-
c語言中關於時間的函數
本文從介紹基礎概念入手,探討了在C/C++中對日期和時間操作所用到的數據結構和函數,並對計時、時間的獲取、時間的計算和顯示格式等方面進行了闡述。本文還通過大量的實例向你展示了time.h頭文件中聲明的...- sven_007
- 2012年06月26日 10:00
- 3293
-
C語言time.h中clock()函數的使用
C語言中求程序執行的時間可以使用clock()函數,_CRTIMP clock_t __cdecl __MINGW_NOTHROW clock (void);(可以把它直接視爲clock_t cloc...- wangluojisuan
- 2011年12月05日 20:48
- 23730
-
C語言再學習 -- 時間函數
在軟件設計中經常會用到關於時間的處理,用來計算語句、函數的執行時間,這時就需要精確到毫秒甚至是微妙的時間。我們首先來介紹一下,時間單位:時間單位還有:毫秒(ms)、微秒 (μs)、納秒(ns)、皮...- qq_29350001
- 2017年01月14日 16:46
- 1421
-
C語言中常用"計時"方法總結
C語言中常用計時方法總結 1. time() 頭文件:time.h 函數原型:time_t time(time_t * timer) 功能:返回以格林尼治時間(GMT)爲標準,從1970年1月...- suifenghahahaha
- 2017年05月09日 17:11
- 400
-
c ms/毫秒級 計時 及time.h 其它函數詳解
C/C++中的日期和時間 摘要: 本文從介紹基礎概念入手,探討了在C/C++中對日期和時間操作所用到的數據結構和函數,並對計時、時間的獲取、時間的計算和顯示格式等方面進行了闡述。本文還通過大量的實例向...- onezeros
- 2009年09月16日 18:32
- 20714
-
C\C++中計時、延時函數
C\C++標準庫中提供了兩種計時函數clock()和time()。其用法如下: (1)clock()函數用法void timeConsume(){ double start,stop,...- keith_bb
- 2016年11月06日 18:25
- 9437
-
C/C++ 各種計時函數總結
本文對Windows平臺下常用的計時函數進行總結,包括精度爲秒、毫秒、微秒三種精度的5 種方法。分爲在標準C/C++下的二種time()及clock(),標準C/C++所以使用的time()及cloc...- u010962810
- 2013年10月07日 15:53
- 2858
-
Windows 各種計時函數總結
本文對Windows平臺下常用的計時函數進行總結,包括精度爲秒、毫秒、微秒三種精度的5種方法。分爲在標準C/C++下的二種time()及clock(),標準C/C++所以使用的time()及clock...- MoreWindows
- 2011年10月09日 10:42
- 46703
-
C語言寫的一個鐘錶(很炫哦)
下面是源代碼: #include#include#include#include#define PI 3.1415926#define x 320#define y 240int main(){ in...- Terry001
- 2007年09月15日 21:15
- 1866
-
C語言寫的一個電子時鐘
C語言的電子時鐘- qq_34400232
- 2017年03月05日 14:58
- 1238
-
C語言控制檯的數字時鐘
轉自:http://hi.baidu.com/csxwczj/item/68cd6e0f056da6eaf55ba67f/*TC2.0編譯*/#include #include #inclu...- qugename
- 2013年04月07日 22:04
- 1543
-
C語言編寫時鐘程序
使用C語言編寫的時鐘程序,TC下通過,VC需要有graphics包,這個包可以去easyx下載,下載地址爲:http://www.easyx.cn/downloads/,下載下來安裝就可以了。以下...- u010394032
- 2013年11月03日 18:03
- 2900