測量程序運行時間

一:基於Timer的測量方法。

缺點:精度不夠高,不能用於程序運行持續時間小於100ms的測量。
優點:準確性不是十分依賴於系統負載,並且在執行時間大於1s的程序上,與理論值之間的誤差很低。
方法:在程序開始時讀取計時器的內容,在程序終止前再次讀取Timer的內容。主要的接口函數有:
Unix/Linux:
clock_t times(struct tms *buf);
//return value:系統自啓動以來經過的時間滴答數,常數CLK_TCK表示每秒經過的時鐘滴答數
//parameter:一個指向tms結構的指針
//使用該函數時要包含頭文件<sys/times.h>
Win32:
DWORD GetTickCount(VOID)
//return value:the number of milliseconds that have elapsed since the system was started.
//使用時應包含<windows.h>,link階段應鏈接 kernel32.lib

如果要編寫可進行平臺移植的代碼,可以利用下面的函數:
clock_t clock(void)
//常數CLOCKS_PER_SEC保證將該函數返回的值格式化爲秒數
//使用該函數時要包含頭文件<time.h>

二:基於Counter的測量方法。

缺點:只能用彙編語言讀取,不能保證通用性,在系統負載很大的情況下,將極大的影響準確性
優點:精度高,並且因爲得到的是程序執行期間所經過的時鐘週期數,所以可大致估算出在不同硬件平臺上程序的執行時間。
方法:在IA32體系結構中,CPU內部有一個被稱爲“時間戳(TimeStamp)”的64位無符號數計數器,存儲自cpu上電以來所經過的時鐘週期數。

一:WIN32中有一個QueryPerformanceCouter函數讀取的就是一個64位的計數器.

二:目前的compiler有的不支持RDTSC指令,如果在這種compiler下,可以利用__emit指令繞過compiler執行,應該在文件頭加入:
#define CPUID __asm __emit 0fh __asm __emit 0a2h
#define RDTSC __asm __emit 0fh __asm __emit 031h
微軟的C/C++編譯器從6.0版開始支持CPUID和RDTSC指令,所以可以直接在程序中嵌入彙編代碼,下面是一個簡單示例:
#include<stdio.h>
int main()
{
unsigned int cycle,i;
__asm
{
CPUID
RDTSC
mov cycle,eax
}
for(i=0;i<10000;i++)
;
__asm
{
CPUID
RDTSC
sub eax,cycle
mov cycle,eax
}
printf("the program duration cycle = %d/n",cycle);
return 0;
}
由於基於counter的測量方法受影響的因素較多,主要是Context Switch和Instruction Cache的影響,所以高精度計時必須設法消除上述兩種因素的影響,對Context Switch主要是採用在負載低的機器上多次計算求平均,而對Instruction Cache多采用提前載入需要測試代碼段的Instruction,然後執行測量的方法.具體做法參見
http://www.cs.usfca.edu/~cruse/cs210/rdtscpm1-1.pdf
Computer System: A programmer's perspective(Chapter 7) 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章