精確測量程式執行時間

2021-06-04 00:06:41 字數 2260 閱讀 8430

作為乙個程式設計師,很多時候都會去關心自己的程式跑的到底有多快,這時就需要對程式的執行時間進行測量。對於不同的程式,它們的執行時間可能相差很大。諸如科學計算類的程式,由於計算量大且演算法的並行化比較差,可能幾天都跑不完。而有的程式的執行時間可能只有幾分鐘甚至不到1ms。不同的時間測量方法,其測量精度和實現難度均有所不同。正因如此,我們要學會選擇合適的方法,來滿足對測量精度的不同需求。下面就按照測量精度遞增的順序簡單介紹幾種方法(精度範圍:s~ms~us)

1,指令碼實現(精度:s)

在windows下面,可以在程式開始前將當前時間用"time /t >time.txt"命令,將程式的啟動時間存到time.txt檔案中,然後在程式結束後再用"time /t >>time.txt"將當前時間追加到檔案的第二行。這樣,兩次的時間值相減即可得到程式的執行時間差。當然,如果程式的執行時間跨越了凌晨12:00,可以考慮配合"date /t"命令一起使用。這樣即使你跑個幾年也不會有問題

在linux下面,這個工作就更簡單了,直接"time $command"就能看到執行時間了。         

分析:正常情況下,此方法的誤差應該不超過2s,因此如果你的程式的執行時間遠大於2s,可以考慮用此方法。

2,利用語言或者系統提供的api。(精度:ms)

clock_t start = clock();

yourcodehere();

clock_t end = clock();

printf("time cost is : %lf", (double)(end - start) / clocks_per_sec);

在windows中,也提供了相關的api,如gettickcount()等。

分析:精度可以達到毫秒級,它們讀取的是bios裡面的real time值,或者叫做牆上時鐘(ps:bios裡面有個專門的暫存器,用來記錄從2023年到現在為止的毫秒值,並且有一塊單獨的電池為此時鐘進行供電,因此即使掉電這個時鐘也照樣跑)

3,用單獨的彙編指令序列來實現(精度:us甚至幾十ns)

對於每乙個好奇的程式設計師或者是十分關心**效能的程式設計師來說,他絕對不會滿足於毫秒級的時間準確度。他們甚至想去測量自己的某幾行甚至是一行指令花了多少時間,而這些時間一般都是微秒級的。下面我們就嘗試著做這樣一件事。

在x86的處理器裡面,有乙個暫存器叫time stamp counter,它在系統啟動時被初始化為0並在每個cycle的時候加1。因此通過2次讀取該暫存器的值,並求其差值我們就可以粗略得到程式的執行時間。說粗略主要是因為我們假設**執行期間不被打斷,而且在深度流水且亂序執行的處理器上,想要通過跑**這種物理方法來得到指令的準確執行時間是不可能的。下面就是這種方法的**實現:

rdtsc

mov [start_low],eax

mov [start_high],edx

xor eax,eax

cpuid

your_code_here

xor eax,eax

cpuid

rdtsc

mov [end_low],eax

mov [end_high],edx

(end_high<<32)+end_low-(start_high<<32)-end_high ,就能得到執行時間了。

說明:1,此方法計算得到的實際上是**的執行所花的cycles,而並不是時間,如果要測時間,還須再去除以處理器的主頻。如果處理器的主頻變了,這樣測得的時間將沒有任何意義。不過,很多時候,貌似cycles比時間更具參考意義。

2,此方法測得的也並非嚴格的cycles,因為在兩次rdtsc之間不僅加入了記憶體操作指令,而且還有兩次的cpuid和xor eax,eax。即使我們做了不少努力來減少誤差,但不得不說我們這樣的**也著實有點「**」,試問誰沒事寫**的時候會去主動排空流水線,想塞滿還來不及呢。換句話說,我們所使用的手段已經讓被測**跟實際應用中的場景產生了不少距離。用量子力學中的一句話來說,針對物體的任何測量都不可避免的引起該物體的變化。

3,此方法的測量時間誤差大約在幾十個cycles(也即幾十個ns),因此不適合單條指令時間的測量,但是對於us級的**應該還是沒問題的。

4,在amd的處理器上,time stamp counter的值貌似不是每個cycle增加一次,我的turion tl-60測量結果貌似是2個cycle增加一次。

對於時間的測量,看似是個簡單的問題,但是要想把它做得那麼盡善盡美似乎也沒那麼容易。另外,在實際應用中,一定要根據自己的需要選擇最經濟實惠的方法。

1,《code optimization:有效使用記憶體》by kris kapersky。

實力有限,歡迎拍磚。

如何精確測量程式執行時間

在網上找了很久試了很久,感覺這個是最好的,拿出來分享下。bool queryperformancefrequency large integer lpfrequency 返回硬體支援的高精度計數器的頻率。bool queryperformancecounter large integer lpcou...

如何精確測量程式執行時間

在網上找了很久試了很久,感覺這個是最好的,拿出來分享下。bool queryperformancefrequency large integer lpfrequency 返回硬體支援的高精度計數器的頻率。bool queryperformancecounter large integer lpcou...

timeofday測量程式執行時間

2.時間的測量 有時候我們要計算程式執行的時間.比如我們要對演算法進行時間分析.這個時候可以使用下面這個函式.include int gettimeofday struct timeval tv,struct timezone tz strut timeval gettimeofday將時間儲存在結...