→ suhorng:你可以懷疑是被優化掉了XD?07/20 11:18
之前要和你做的事情差不多,但情況比你嚴重, #1DoEorL- ,我簡單的說,
這是 Visual C++ 開 O2 的問題,版神 purpose 也驗證過。
推 purpose:剛也測了,跑很多次 f = pow(f, 2.0) 拖時間,如果用/O1我05/10 18:21
→ purpose:家爛電腦跑出td=437,如果用/O2,則compiler太精了,根本05/10 18:22
→ purpose:不做中間的pow計算,直接連續呼叫clock()得到td=005/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);
雖我已有加輸出動作,最後我實測結果還是會失敗,另一位版神出手
推 legnaleurc: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)
推 xatier:推鎮板之神t大<(_ _)> 07/20 14:31
推 ericinttu:QueryPerformanceCount / QueryPerformanceFrequency 07/20 15:07
→ ericinttu:這個精度應該夠用了. 07/20 15:07
推 ericinttu:不過... 做這種基本的運算, 看要不要在C平台上寫組語? 07/20 15:27
→ ericinttu:把一些自動化干擾因素去掉, 也比較客觀一點 (是一點噢) 07/20 15:28
推 Ross0916:QueryPerformanceCounter? 07/20 17:20
→ Ross0916:不準的啦,比如你的防毒軟體不是在背景監控嗎orz 07/20 17:21
→ tropical72:是 QueryPerformanceCounter 才對,謝謝指正。 07/20 17:21
→ Ross0916:只有自己寫OS,把所有 interrupt 關掉....XD 07/20 17:21
→ tropical72:@@ 我電腦真沒用防毒,可能會有其它因素影響.. 07/20 17:22
→ tropical72:Ross大一說,我又開始好奇學術paper的數據怎來的.. 07/20 17:28
推 Ross0916:我也不知道..大概是測一般使用情況下的速度吧.. 07/20 17:30
→ Ross0916:所以也許本來就不需要那麼準.. 07/20 17:30
→ kdjf:這種東西為什麼不用asm下去直接數mechine cycle? 07/20 18:11
推 littleshan:rdtsc要小心,因為多核的cpu也有多個timestamp counter 07/20 18:51
→ littleshan:如果你的process context-switch到另一個core就不準了 07/20 18:51
→ littleshan:要準確的話,我覺得用simulator是最準的 07/20 18:53
→ tropical72:可否指點一下 simulator 是 ?? 07/20 19:15
→ firejox:模擬? 07/20 20:05
→ xatier:模擬器? 07/20 20:32
→ suhorng:@kdjf 現在都流水線, 數machine cycle也沒用... 07/20 20:51
→ diabloevagto:用profile可以嗎? 07/20 21:23
→ tropical72:@diabloevagto: 原po的問題,開O2連編都沒編進去,但若 07/20 22:31
→ tropical72:編進去後再用profile應是個不錯的選擇. 07/20 22:31
推 horngsh:演算法這種東西注重的不是應該是執行"次數"才對嗎? 即時間 07/21 06:25
→ horngsh:複雜度分析! 07/21 06:25
→ tropical72:@horngsh:這問題..簡單的+-*/mod運算,在不考慮特殊數 07/21 07:30
→ tropical72:值情況下,Big-O 都相等的話那還要怎麼比較? 07/21 07:31
→ firejox:用大數想法.... 07/21 10:47
推 horngsh:用超大數代入計算來做Big-O 分析 07/21 19:25
→ horngsh:以除法而言, 可以指定算幾十位小數點的無限小數.這樣就可 07/21 19:27
→ horngsh:以分析了 07/21 19:28