一個陣列初始化問題 |
|
shihyu
一般會員 ![]() ![]() 發表:20 回覆:17 積分:7 註冊:2002-11-30 發送簡訊給我 |
|
Stallion
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:52 回覆:1600 積分:1995 註冊:2004-09-15 發送簡訊給我 |
|
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
雖然結果都是 int a[ ] = {0} 的方式比較快,但原因不全然是因為在complie time 時決定的關係。
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
抱歉,剛注意到我忘了把GodeGuard關起來,導致多呼叫了CG_LDA_EOXSY( )
把程式重跑一下… 我實測a[100000]的結果大概是 for 用了1,193,851 {0} 則用了 346,143 cycles 近3.4倍的差異 ===================引 用 文 章=================== 而for的話則用許多的微指令
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
shihyu
一般會員 ![]() ![]() 發表:20 回覆:17 積分:7 註冊:2002-11-30 發送簡訊給我 |
===================引 用 文 章=================== 抱歉,剛注意到我忘了把GodeGuard關起來,導致多呼叫了CG_LDA_EOXSY( ) 把程式重跑一下… 我實測a[100000]的結果大概是 for 用了1,193,851 {0} 則用了 346,143 cycles 近3.4倍的差異 ===================引 用 文 章=================== 而for的話則用許多的微指令 __________________________________________________________________________________ 請問是用BCB 去測試效率嗎??? 可以教一下怎麼測試嗎??? 很想知道怎麼去做測試 謝謝
|
shihyu
一般會員 ![]() ![]() 發表:20 回覆:17 積分:7 註冊:2002-11-30 發送簡訊給我 |
===================引 用 文 章=================== 抱歉,剛注意到我忘了把GodeGuard關起來,導致多呼叫了CG_LDA_EOXSY( ) 把程式重跑一下… 我實測a[100000]的結果大概是 for 用了1,193,851 {0} 則用了 346,143 cycles 近3.4倍的差異 ===================引 用 文 章=================== 而for的話則用許多的微指令 To aftcast 請問用bcb 測到的 cycles 是指需使用到的微指令行數嗎??? 可以請問一下用 bcb 測試 cycles 要如何去使用它 謝謝
|
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
並非微指令行數,是cpu時脈下經過了多少次。所以每台測的結果會有些不同,因為時脈不同。 測的方式是用自定的time-stamp counter function來實作的,所以不一定要在bcb裡,只要能使用inline assembly就可以。請參加我的程式: (for BCB) __int64 GetCounter(void) 在你想要測的片段statements的前面和後面取數,相減得差,就可以知道約經過多少個cycles。 PS. 這個function本身會得到一個warnning,說是沒有return值。這是沒關係的,因為rdtsc這個微指令執行完成後就會把counter計入EDX:EAX上,而我們這個function使用__int64為回傳值,剛好就是會return EDX:EAX ! 另外,不是所有的語言的inline asm都有support這個指令,所以在不同的語言上可能需要做調整,或是直接給opcode等… To aftcast 請問用bcb 測到的 cycles 是指需使用到的微指令行數嗎??? 可以請問一下用 bcb 測試 cycles 要如何去使用它 謝謝
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
shihyu
一般會員 ![]() ![]() 發表:20 回覆:17 積分:7 註冊:2002-11-30 發送簡訊給我 |
//--------------------------------------------------------------------------- #include //--------------------------------------------------------------------------- __int64 GetCycleCount(void)
t = (unsigned long)GetCycleCount(); for (i ; i <= 10000; i ) cout << t << endl; system("pause");
不過下面測試 int a[10000] = {0} ; 這樣可以跑出一組數據 t = (unsigned long)GetCycleCount(); int a[10000] = {0}; t -= (unsigned long)GetCycleCount();
謝謝 |
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
for (i ; i <= 10000; i ) <<---是不是因為 i 沒初始化的關係?
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
|
shihyu
一般會員 ![]() ![]() 發表:20 回覆:17 積分:7 註冊:2002-11-30 發送簡訊給我 |
____________________________________________________________________
//--------------------------------------------------------------------------- #include //--------------------------------------------------------------------------- __int64 GetCounter(void)
我是在console 測試 這樣還是跑不出數據 =.= |
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
剛把你的程式貼到我的project裡測式,發現… for (i = 0 ; i < 10000; i ) 你再試看看吧!
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
shihyu
一般會員 ![]() ![]() 發表:20 回覆:17 積分:7 註冊:2002-11-30 發送簡訊給我 |
===================引 用 文 章=================== 剛把你的程式貼到我的project裡測式,發現… for (i = 0 ; i < 10000; i ) 你再試看看吧! _______________________________________________________________________________ 原來是出超範圍 @@ .... 抱歉我搞笑了 .... BCB 用 for Tab 後自動產生 (i = 0; i <= 10; i ) 因為很不常使用BCB 所以沒有留意 <= 問題 =.= 謝謝 |
shihyu
一般會員 ![]() ![]() 發表:20 回覆:17 積分:7 註冊:2002-11-30 發送簡訊給我 |
|
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
最新研究報告出來了!!
1/ 每次不太一樣是正常的,因為這是多工的環境,但值應該都平均接近 2/ 根據我反組譯程式看,發現一個我沒想過的事… 若是用 [ ] = {0} 的方式,complier是會把整個陣列先當作外在變數一樣,把整個陣列放入程式exe檔內(以ASM來說,就是DATA區段內),於是即使在函式內宣告 a[10000] = {0}; 照常還是會造成exe檔變大! 可以試著把陣列變很大,你會看到exe檔變超大的 -_-||| 。當實際上跑的時候才又使用rep movsd微指令把.DATA區的資料copy到stack上…這與用for是不一樣的,當你在函式內宣告b[10000]是不會在.DATA區內有值,而是在實際上跑的時候,在Stack上劃出一塊來放,然後用for把值一個一個的設定到區塊。所以,就算b宣告超級大,檔案還是不會變! (如原本所知的情形) 3/ 但就 rep movsd 與 for 所用的微指令來比較,rep movsd的確是比較快。因為他只用了7 4n個cycles (n次),而for裡面的mov 就要2個cycle,但不只mov 一次,等等…所以 rep movsd一定比較快! 4/ 然而…為什麼第一次跑的數據爆大,然後才又變小?? 我推斷是因為windows paging的關係。事實上當程式在跑的時候,並不是整個exe全部load至記憶體,而是部份在RAM上,部份在disk上(swarp)。而當我們需某些資料的時候才立刻把swarp的資料載入RAM上,這種過程就是paging。因為windows 有cache的能力,同樣的程式被載入第二次一定會比第一次快(可以試著開word之類的,開了再關)。所以,應該是第一次的.DATA資料還在swarp中,值到處理至rep movsd時因為動到了DATA區的資料,所以才被載入RAM上,才開始一個一個的copy資料。這個載入的過程就花了不少的時間。而當第二次再跑程式的時候,DATA區的資料已在RAM上,就沒有載入的問題,於是就看出rep movsd真正的速度! 5/ 實驗: 可以把程式編好後copy(不能用rename)至另一個檔名,用新的檔案來跑,第一次又變慢,第二次又快。同樣的程式在copy至另一個新名字,也有同樣的情形。這就是windows cache的能力! 6/結論: 從上面的事實來看覺得內在變數還是乖乖的使用for來處理,因為A/執行檔不會變大B/若只會此function只被叫用一次,那就虧更大了C/for的方式與rep movsd 的方式僅差3倍左右,應該算還好。當然,若陣列值小的時候,比如說1000個 int值,那麼檔案多增4k左右,但速度變快,且沒有第一次,第二次的問題,因為整個區塊小,開始的時候可能就都被載入RAM中了。 ===================引 用 文 章=================== 請問 cycle 值是不是每次跑出來的值都不太一樣 , 這樣是正常嗎 ??cycle 每次跑數據都不 一樣是什麼原因?? 我用 int a[10000] = {0} 的cycle 值 > 大於 for 的cycle 值 .... >< 還有一個怪問題 當我第ㄧ次跑 int a[10000] = {0} ; 是50幾萬 , 再讓它跑第一次下降到10幾萬 , 之後測試都是10幾萬 還是需要哪邊要設定之類的?? 謝謝
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |