国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

【C/C++】計時函數比較

2019-11-10 18:20:18
字體:
來源:轉載
供稿:網友

轉自:http://www.cnblogs.com/dwdxdy/p/3214905.html

目前,存在著各種計時函數,一般的處理都是先調用計時函數,記下當前時間tstart,然后處理一段程序,再調用計時函數,記下處理后的時間tend,再tend和tstart做差,就可以得到程序的執行時間,但是各種計時函數的精度不一樣.下面對各種計時函數,做些簡單記錄.

  方法1,time()獲取當前的系統時間,返回的結果是一個time_t類型,其實就是一個大整數,其值表示從CUT(Coordinated Universal Time)時間1970年1月1日00:00:00(稱為UNIX系統的Epoch時間)到當前時刻的秒數.

void test1(){ time_t start,stop; start = time(NULL); foo();//dosomething stop = time(NULL);   方法2,clock()函數返回從“開啟這個程序進程”到“程序中調用clock()函數”時之間的CPU時鐘計時單元(clock tick)數,在MSDN中稱之為掛鐘時間(wal-clock)

常量CLOCKS_PER_SEC,它用來表示一秒鐘會有多少個時鐘計時單元

void test2(){ double dur; clock_t start,end; start = clock(); foo();//dosomething end = clock(); dur = (double)(end - start); printf("Use Time:%f/n",(dur/CLOCKS_PER_SEC));}

方法3,timeGetTime()函數以毫秒計的系統時間。該時間為從系統開啟算起所經過的時間,是windows api

void test3(){ D
Word t1,t2; t1 = timeGetTime(); foo();//dosomething t2 = timeGetTime(); printf("Use Time:%f/n",(t2-t1)*1.0/1000);}

方法4,QueryPerformanceCounter()這個函數返回高精確度性能計數器的值,它可以以微妙為單位計時.但是QueryPerformanceCounter()確切的精確計時的最小單位是與系統有關的,所以,必須要查詢系統以得到QueryPerformanceCounter()返回的嘀噠聲的頻率.QueryPerformanceFrequency()提供了這個頻率值,返回每秒嘀噠聲的個數.

void test4(){ LARGE_INTEGER t1,t2,tc; QueryPerformanceFrequency(&tc); QueryPerformanceCounter(&t1); foo();//dosomething QueryPerformanceCounter(&t2); printf("Use Time:%f/n",(t2.QuadPart - t1.QuadPart)*1.0/tc.QuadPart);}

方法5,GetTickCount返回(retrieve)從操作系統啟動到現在所經過(elapsed)的毫秒數,它的返回值是DWORD

void test5(){ DWORD t1,t2; t1 = GetTickCount(); foo();//dosomething t2 = GetTickCount(); printf("Use Time:%f/n",(t2-t1)*1.0/1000);}

方法6,RDTSC指令,在Intel Pentium以上級別的CPU中,有一個稱為“時間戳(Time Stamp)”的部件,它以64位無符號整型數的格式,記錄了自CPU上電以來所經過的時鐘周期數。由于目前的CPU主頻都非常高,因此這個部件可以達到納秒級的計時精度。這個精確性是上述幾種方法所無法比擬的.在Pentium以上的CPU中,提供了一條機器指令RDTSC(Read Time Stamp Counter)來讀取這個時間戳的數字,并將其保存在EDX:EAX寄存器對中。由于EDX:EAX寄存器對恰好是Win32平臺下C++語言保存函數返回值的寄存器,所以我們可以把這條指令看成是一個普通的函數調用,因為RDTSC不被C++的內嵌匯編器直接支持,所以我們要用_emit偽指令直接嵌入該指令的機器碼形式0X0F、0X31

inline unsigned __int64 GetCycleCount(){ __asm { _emit 0x0F; _emit 0x31; }}void test6(){ unsigned long t1,t2; t1 = (unsigned long)GetCycleCount(); foo();//dosomething t2 = (unsigned long)GetCycleCount(); printf("Use Time:%f/n",(t2 - t1)*1.0/FREQUENCY); //FREQUENCY指CPU的頻率}

  方法7,gettimeofday() linux環境下的計時函數,int gettimeofday ( struct timeval * tv , struct timezone * tz ),gettimeofday()會把目前的時間有tv所指的結構返回,當地時區的信息則放到tz所指的結構中.

//timeval結構定義為:struct timeval{long tv_sec; /*秒*/long tv_usec; /*微秒*/};//timezone 結構定義為:struct timezone{int tz_minuteswest; /*和Greenwich 時間差了多少分鐘*/int tz_dsttime; /*日光節約時間的狀態*/};void test7(){ struct timeval t1,t2; double timeuse; gettimeofday(&t1,NULL); foo(); gettimeofday(&t2,NULL); timeuse = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec)/1000000.0; printf("Use Time:%f/n",timeuse);}

  方法8,linux環境下,用RDTSC指令計時.與方法6是一樣的.只不過在linux實現方式有點差異.

#if defined (__i386__)static __inline__ unsigned long long GetCycleCount(void){ unsigned long long int x; __asm__ volatile("rdtsc":"=A"(x)); return x;}#elif defined (__x86_64__)static __inline__ unsigned long long GetCycleCount(void){ unsigned hi,lo; __asm__ volatile("rdtsc":"=a"(lo),"=d"(hi)); return ((unsigned long long)lo)|(((unsigned long long)hi)<<32);}#endifvoid test8(){ unsigned long t1,t2; t1 = (unsigned long)GetCycleCount(); foo();//dosomething t2 = (unsigned long)GetCycleCount(); printf("Use Time:%f/n",(t2 - t1)*1.0/FREQUENCY); //FREQUENCY CPU的頻率}

簡單的比較表格如下

序號 函數 類型 精度級別 時間 1 time C系統調用 低 <1s 2 clcok C系統調用 低 <10ms 3 timeGetTime Windows API 中 <1ms 4 QueryPerformanceCounter Windows API 高 <0.1ms 5 GetTickCount Windows API 中 <1ms 6 RDTSC 指令 高 <0.1ms 7 gettimeofday linux環境下C系統調用 高 <0.1ms

  總結,方法1,2,7,8可以在linux環境下執行,方法1,2,3,4,5,6可以在windows環境下執行.其中,timeGetTime()和GetTickCount()的返回值類型為DWORD,當統計的毫妙數過大時,將會使結果歸0,影響統計結果. 測試結果,windows環境下,主頻為1.6GHz,單位為秒.

1 Use Time:0 2 Use Time:0.390000 3 Use Time:0.388000 4 Use Time:0.394704 5 Use Time:0.407000 6 Use Time:0.398684   linux環境下,主頻為2.67GHz,單位為秒

1 Use Time:1 2 Use Time:0.290000 7 Use Time:0.288476 8 Use Time:0.297843 由于time()計時函數的精度比較低,多次運行程序時,將會得到不同的結果,時而為0,時而為1

foo()函數如下:

void foo(){ long i; for (i=0;i<100000000;i++) { long a= 0; a = a+1; }}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 云梦县| 美姑县| 康平县| 仙桃市| 珠海市| 固始县| 黔南| 洛扎县| 荣昌县| 沾益县| 色达县| 若尔盖县| 佛冈县| 海林市| 东兰县| 朔州市| 桓台县| 墨脱县| 贺兰县| 新营市| 曲阳县| 涞源县| 伊宁县| 本溪| 铜鼓县| 光山县| 吕梁市| 安新县| 翁源县| 米脂县| 衡东县| 阜阳市| 红河县| 敖汉旗| 锦屏县| 九寨沟县| 宁武县| 徐汇区| 信丰县| 成都市| 汕头市|