Re: [問題] 如何精準計算 運算元(+ - * /)時間

看板C_and_CPP作者 (藍影)時間14年前 (2011/07/20 14:27), 編輯推噓8(8024)
留言32則, 10人參與, 最新討論串2/2 (看更多)
這是一大段測時的問題, 既你是用 Visual Studio C++, 那我一次把心得全放上來, 免得你日後還會有問題。 先聲明一件事, 我對 asm 分析不行, 但對 wall time 分析應算小有研究。 ※ 引述《ouyang0916 ()》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : VC++ 這是一個重點,記得標版本。 : 錯誤結果(Wrong Output): : 0 (時間太快?我做了10000000次也是這個結果) : 程式碼(Code):(請善用置底文網頁, 記得排版) : http://dpaste.com/hold/571946/ : 補充說明(Supplement): : 我還想測試 加法 減法 模數 乘法 ...等時間分析  : 感謝大大們的指導 恕刪。 ---------------

07/20 11:18,
你可以懷疑是被優化掉了XD?
07/20 11:18
之前要和你做的事情差不多,但情況比你嚴重, #1DoEorL- ,我簡單的說, 這是 Visual C++ 開 O2 的問題,版神 purpose 也驗證過。

05/10 18:21,
剛也測了,跑很多次 f = pow(f, 2.0) 拖時間,如果用/O1我
05/10 18:21

05/10 18:22,
家爛電腦跑出td=437,如果用/O2,則compiler太精了,根本
05/10 18:22

05/10 18:22,
不做中間的pow計算,直接連續呼叫clock()得到td=0
05/10 18:22
for(i=0;i<size;i++){ x=Logistic(x); //chaos map k=ftoint(x); //Flotation point number to integer conversion } time2 = clock(); 原因在於, VC 他太聰明了, 他知道你這裡的 k 是白算的, 因為最後結果根本沒用到 k, 所以開 O2 時就避掉了, 我猜那段根本就沒放進來, 你可適當的在 time2 「之後」做這件事:printf("k=%d\n", k); 即時這樣,目前你算出來的應還是 0 secs,這次的原因是在於「是真的太快」。 以下有幾種解法,可適用於大多數的情況 -------------- 1. 執行 TIMES 次 #define TIMES UINT_MAX unsigned times=TIMES; t1=clock(); while(--times) { // initialize value // your test function } t2=clock(); 評論:這方法是我常用的,但這方法本身就有用到減法、比較指令, 而你本身要測的就是五則運算,可能不會非常準。 --------------- 2. 換計時器 其實你有一段碼是沒意義的 printf (" %.20f seconds \n", total ); (a) 浮點數精度只到 15.22 位,意思是到第 16 位完全沒參考價值。 (b) 計時器本身誤差問題 : 計時器本身就會有誤差, 這裡的誤差和精度(CLOCK_PER_SEC)並不一樣,意思是 clock() 誤差不只 1ms 我是沒測過 clock() 本身誤差是多少, 但可以確定的是, 是「數十」個 ms (可能是 16~55 ) Visual C++ 要其它計時器的話 http://edisonx.pixnet.net/blog/post/52113788 你的問題我建議用 QueryPerformanceCount / QueryPerformanceFrequency, 同樣的 code, 加上輸出 k, 我這裡最後得到的不是 0 sec, 而是 0.0004134603699632 seconds. 要更精準的話, Visual C++ 調用 __rdtsc() http://msdn.microsoft.com/en-us/library/twchhe95(v=vs.80).aspx 但這指令有公開爭論、討伐過, 好不好用, 待議 (我本身會用就是了) ------------------ 3. 以上步驟仍失敗的話 目前你上面的 code 加輸出就正常了, 以後未必。 我截取 #1DoEorL- (C_and_CPP) 這段文章 裡的一段 code t1 = clock(), cnt=PrimeCnt(N), t2 = clock(); printf("cnt=%d, td=%d\n", cnt,t2-t1); 雖我已有加輸出動作,最後我實測結果還是會失敗,另一位版神出手

05/10 15:54,
volatile ?
05/10 15:54
這加上去後, 會影響 compiler 優化結果, 所以後來我另劈出路。 最後我包成 function pointer , 再以 function pointer 間接呼叫 test function 奇妙的事情是這問題解決了。 ------------------ 4. 記得詳細註明你的開發環境 因為我相關背景知識弱,所以在做測時開發時會測好幾次, compiler 我會測過 Dev-C、Visual C++, 同一台電腦,這二個 compile 出來的執行檔,執行結果會讓人意外, 結果確實也關係到 Dev-C、Visual C++ 優化怎麼開。 CPU 我本身是 AMD,換到 Intel 後結果又不一樣, 不只是時間上增加/縮短,而是方法的快慢 order 整個都不一樣。 這樣一份程式碼前前後後就測了 4 次, ( 後來才「聽說」,一般測試基本上是以 Intel CPU 為主,沒驗證這件事) 不同 cpu、不同 compiler、不同優化,function 的 rank 就可能會有所不同。 -------------------- 以上一點經驗, 供參考。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.78.41 ※ 編輯: tropical72 來自: 180.177.78.41 (07/20 14:30)

07/20 14:31, , 1F
推鎮板之神t大<(_ _)>
07/20 14:31, 1F

07/20 15:07, , 2F
QueryPerformanceCount / QueryPerformanceFrequency
07/20 15:07, 2F

07/20 15:07, , 3F
這個精度應該夠用了.
07/20 15:07, 3F

07/20 15:27, , 4F
不過... 做這種基本的運算, 看要不要在C平台上寫組語?
07/20 15:27, 4F

07/20 15:28, , 5F
把一些自動化干擾因素去掉, 也比較客觀一點 (是一點噢)
07/20 15:28, 5F

07/20 17:20, , 6F
QueryPerformanceCounter?
07/20 17:20, 6F

07/20 17:21, , 7F
不準的啦,比如你的防毒軟體不是在背景監控嗎orz
07/20 17:21, 7F

07/20 17:21, , 8F
是 QueryPerformanceCounter 才對,謝謝指正。
07/20 17:21, 8F

07/20 17:21, , 9F
只有自己寫OS,把所有 interrupt 關掉....XD
07/20 17:21, 9F

07/20 17:22, , 10F
@@ 我電腦真沒用防毒,可能會有其它因素影響..
07/20 17:22, 10F

07/20 17:28, , 11F
Ross大一說,我又開始好奇學術paper的數據怎來的..
07/20 17:28, 11F

07/20 17:30, , 12F
我也不知道..大概是測一般使用情況下的速度吧..
07/20 17:30, 12F

07/20 17:30, , 13F
所以也許本來就不需要那麼準..
07/20 17:30, 13F

07/20 18:11, , 14F
這種東西為什麼不用asm下去直接數mechine cycle?
07/20 18:11, 14F

07/20 18:51, , 15F
rdtsc要小心,因為多核的cpu也有多個timestamp counter
07/20 18:51, 15F

07/20 18:51, , 16F
如果你的process context-switch到另一個core就不準了
07/20 18:51, 16F

07/20 18:53, , 17F
要準確的話,我覺得用simulator是最準的
07/20 18:53, 17F

07/20 19:15, , 18F
可否指點一下 simulator 是 ??
07/20 19:15, 18F

07/20 20:05, , 19F
模擬?
07/20 20:05, 19F

07/20 20:32, , 20F
模擬器?
07/20 20:32, 20F

07/20 20:51, , 21F
@kdjf 現在都流水線, 數machine cycle也沒用...
07/20 20:51, 21F

07/20 21:23, , 22F
用profile可以嗎?
07/20 21:23, 22F

07/20 22:31, , 23F
@diabloevagto: 原po的問題,開O2連編都沒編進去,但若
07/20 22:31, 23F

07/20 22:31, , 24F
編進去後再用profile應是個不錯的選擇.
07/20 22:31, 24F

07/21 06:25, , 25F
演算法這種東西注重的不是應該是執行"次數"才對嗎? 即時間
07/21 06:25, 25F

07/21 06:25, , 26F
複雜度分析!
07/21 06:25, 26F

07/21 07:30, , 27F
@horngsh:這問題..簡單的+-*/mod運算,在不考慮特殊數
07/21 07:30, 27F

07/21 07:31, , 28F
值情況下,Big-O 都相等的話那還要怎麼比較?
07/21 07:31, 28F

07/21 10:47, , 29F
用大數想法....
07/21 10:47, 29F

07/21 19:25, , 30F
用超大數代入計算來做Big-O 分析
07/21 19:25, 30F

07/21 19:27, , 31F
以除法而言, 可以指定算幾十位小數點的無限小數.這樣就可
07/21 19:27, 31F

07/21 19:28, , 32F
以分析了
07/21 19:28, 32F
文章代碼(AID): #1E9dL4em (C_and_CPP)
文章代碼(AID): #1E9dL4em (C_and_CPP)