Re: [問題] 常用指令的時脈開銷?
※ 引述《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
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
05/13 16:22, 4F
推
05/13 18:32, , 5F
05/13 18:32, 5F
討論串 (同標題文章)
完整討論串 (本文為第 3 之 3 篇):
問題
5
16