Re: [問題] 常用指令的時脈開銷?

看板C_and_CPP作者 (藍影)時間13年前 (2011/05/13 14:31), 編輯推噓2(203)
留言5則, 4人參與, 最新討論串3/3 (看更多)
※ 引述《DrStein (啤酒肚)》之銘言: (恕刪) : 小弟只知道 x86 : : 整數 加法 -> 2時鐘 : 整數 乘/除 -> 三時鐘數 ( 看架構,沙橋就是兩個時鐘(?)) : 平移,指定該是都一個時鐘數。 : 有這些才好精確定論,程式是卡在記憶體交換上還是運算上 : 有神人可以幫補完這張表嗎 謝謝 (恕刪) 敝非神人, 無以給予該表, 函之。 此問敝探討多時,尋問多方高人 (應納高人,眾皆以 加速怪物 稱之), 惟下探討參之,若言不及義、荒謬至極,乃盼眾人伐之, 敝人當不勝感激! -------------------- 事實上「測時」應是 CS 領域裡面讓人頭痛的問題, 要測 Wall Time (人類時間, 計時器計數, 下簡稱 WT) 還是測 Process Time (程式真正耗掉的時間, asm 分析, 下簡稱 CT, CPU Time) 做 CT 分析時還要考量到 cache miss、os task swap 等問題; 然而 WT 卻是一般人較能為接受的事, 因多數程式要的是 超過 1 sec 之時間, 以下列簡單的 code 來說, int a=123; int x=a/2; //寫法 (a) int x=a>>1; //寫法 (b) 所有有開 optimizer 之 compiler 應理當會編成同樣的 asm, 但若不開 optimizer 之 compiler 分析其 CT,當然是 (b) 較快, 若不以 CT 分析,改以 WT 分析,以下做以參考 t1= __rdtsc(); for(i=0; i!=MAX_INT; ++i) x=a<<1; t2=__rdtsc(); t1= __rdtsc(); for(i=0; i!=MAX_INT; ++i) x=a*2 ; t2=__rdtsc(); 這種測時方式連 loop 等因素都考慮進去的時間,最後能得到: 在無 OS 干擾、無 Cache Miss 下程式可能的(最短)時間 若是「一大段」code,分析時就如 littleshuan 所言, 有許多干擾因素,分析 CT 似乎也不適合, 於是 purpose 與其他先進才建議 profiler, UNIX / LINUX 大多用 GNU profiler Windows 下若為 VC ,記得有自帶 profiler (待查證) Intel 也有一套,應是 Intel VTune, code project 上也有一份 profiler http://www.codeproject.com/KB/cpp/profiler.aspx 這篇在 History 裡有提到不少作者的心得與經驗, 值得細看。 而在測效率的部份,看遍所有網路上的文章, 給的數據目前也只有看過 WT 數據,也就是跑幾億次 loop 時間花多少, 沒人給 CT 數據,也就是沒人分析這麼寫法會省下幾個週期數。 還有個問題要探討: 明明都是數學函式, dev-c 和 msvc 翻出來的 asm code 都一樣 為何活生生的實際上 msvc 跑得比較快? 即使知道這種結果,還要再去分析 asm code 嗎? 以 InvSqrt 為例,測試出來結果如下述連結 http://edisonx.pixnet.net/blog/post/56845924 直接拉到 (5. 測試結果與結論) 明明生成的 asm code 都一樣、電腦用的是同一台, 為何出來的東西不一樣 (有些連方法之 Order 都不一樣)、效能差這麼多[註1]? 裡面也有探討。 順帶一題,若是開優化,真的很難寫贏內建函式 (至少我測的結果,MSVC 上幾乎是不可能的) 再以上述 InvSqrt 為例,當初這個發出來的時候速度驚人! (我是不知道多驚人,不過就是很驚人) 實測結果,普便性卻都比內建的 1.0/sqrt(x) 還慢上 29% (for MSVC) (所以對 MSVC 而言,我認為大概只剩 "欣賞" 的性質) 根本就不知道開 optimizer 後, compiler 偷用了什麼密技、放了什麼大絕。 有點懷疑的話,這裡是其它 math function 的研究報告 log2 for integer http://edisonx.pixnet.net/blog/post/55626354 sqrt for integer http://edisonx.pixnet.net/blog/post/56877450 其它的效能問題,我想關鍵是在於 演算法 部份 程式語言能改善的頂多 3~5 倍,再強的話給個 20 倍好了, (真的要求直接寫 asm 就好了還寫 C) 演算法動不動就是上百、上千、甚至上萬倍, 故我認為是只是「培養」好的寫法、好的習慣 (以加速而言的寫法), 而不是到「走火入魔」的地步,去斤斤計較那一點點的時間, 去想演算法的部份不是更為實際嗎? [註1] 這部份只是放心得而言,提供做 coding 時參考 (1) floating 型態速度 若都是 floating, 但 (float、double、long double) 之表現上會差很多 假設 sizeof(long double) = sizeof(doulbe) = 8 > sizeof(float) = 4 以函式 log 而言, double > float > long double, 以我電腦 (AMD II X2 245 2.91G) 為例 Method 跑10^8 log(double) 5.09812 log(long double) 9.05688 log(float) 9.45124 double > float, 只要有用內建 387的都如此, long double 和 double 之速度應是看 FPU 部份, long double 我所知有 64, 80, 96, 128 bits 若 long double 為 80bits,且 CPU 為 Intel,其 FPU 亦為 80bits, 此時 Speed (long double ) > Speed (double) 至於 integer 處理速度,「應」與 CPU 本身位元數無關, 是以 compiler 所定義之 integer bit 數為主。 的確在語言規格裡面,sizeof(int)*8 = CPU 位元數, 但 MSVC 打破了此規格,故在 64 位元底下裝 VC,sizeof(int) 仍為 4 早期還可以用此法去看 CPU 位元數,現在應不行; 其它的部份,沒軟體、硬體驗證。 至於在速度運算上,是以 int 速度為快, 而非 64 位元CPU 就以 64 位元之整數為快, 即,若為 VC,即使在 64 位元CPU 下之環境, sizeof(int)=4, sizeof(long long int)=8, 但處理上乃以 int 較快。 以上若敘述有誤,請各位不吝指教與更正, 小弟感激不盡。 ------------------- 相關文探討 C_AND_CPP : #1C-99bdi #14EBEVn3 Programming: #1C-98phM #1C-aGNRI -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.73.222

05/13 15:38, , 1F
"int x=a/2; (a)"
05/13 15:38, 1F

05/13 15:38, , 2F
這邊是*?
05/13 15:38, 2F
※ 編輯: tropical72 來自: 180.177.73.222 (05/13 15:42)

05/13 15:43, , 3F
已修正敘述,謝謝建議
05/13 15:43, 3F

05/13 16:22, , 4F
VC 有,但好像是要買貴一點的版本才有附?
05/13 16:22, 4F

05/13 18:32, , 5F
VS2010 似乎是 premium 和 ultimate 有附
05/13 18:32, 5F
文章代碼(AID): #1DpD0nwC (C_and_CPP)
文章代碼(AID): #1DpD0nwC (C_and_CPP)