gcc -faltivec 的迷思
在一些大的 OSS 上很流行針對某種平台或架構作最佳化的編譯動作,像是 Firefox,以前在用 Windows,通常都會用什麼 -msse -msse2 -mcpu=pentium4 等等的選項,來編譯程式。到了 Mac OS X 也不例外,同樣也是有人提供例如 -faltivec -mcpu=7450 -mtune=7450 的編譯版本,來讓使用者盡可能發揮電腦 CPU 的運算單元,利用可以加速的輔助處理器,加快運算速度。就像 firefox 裡面有 JPEG library,DCT 可以加速等等。但是事實上是這樣嗎?我覺得並沒有,其實這些參數可能沒有幫助到什麼。
正確的說,如果 source code 裡面沒有針對這些 architectures 的個別寫出來的 code,那麼儘管加了再多這類 SIMD optimization flags,也是沒用。
舉下面這兩個 c code,
file: test.c接著用 gcc 來編譯:#include <stdio.h> int main( void ) { vector float v1 = { 1., 2., 3., 4. }; vector float v2 = { 2., 3., 4., 5. }; vector float v3; v3=v1 + v2; printf("%vf\n", v3 ); return 0; }file: test2.c#include <stdio.h> int main( void ) { float v1[4] = { 1., 2., 3., 4. }; float v2[4] = { 2., 3., 4., 5. }; float v3[4]; v3[0] = v1[0] + v2[0]; v3[1] = v1[1] + v2[1]; v3[2] = v1[2] + v2[2]; v3[3] = v1[3] + v2[3]; printf("%f\n", v3[0] ); printf("%f\n", v3[1] ); printf("%f\n", v3[2] ); printf("%f\n", v3[3] ); return 0; }
然後可以得到 PowerPC 的組合語言輸出檔案,分別為 test.s 和 test2.s。在這邊擷取其中檔案一部份:gcc-4.0 -faltivec -mcpu=7450 -O3 -c -S
file: test.s可以看到他把 data 載入到 vector registers 去,然後用 AltiVec 指令(v 開頭)加起來。至於 test2.s,完全是 PowerPC 指令,找不到 v 開頭的 instructions。反而要更多倍的指令來把個別的 entry 各自加起來。lvx v1,0,r2 addi r2,r1,64 lvx v0,0,r9 vaddfp v1,v1,v0
假如程式像 test2.c 裡面的 pure C code,那麼加了再多的參數,也不可能讓 gcc 產生 AltiVec 的指令;除非有 directive #ifdef...#else...#endif 來額外編寫針對某種 architecture 的程式碼。所以總之,-faltivec 只是讓 gcc 認得那些額外的 syntax 像是 vector。如果不加,程式有這種寫法,gcc 便會當作未定義的型別。加了,但是程式卻沒有這種針對 vector unit/SIMD 寫法,gcc 也不會幫你產生 AltiVec 的指令來加速運算。那麼為什麼會感覺比較快呢?我的解釋為,可能加了更多針對 G4 general purpose CPU 的 optimization flags,像是 loops 處理、resource allocation、instruction schedule、frame pointer 等等吧。
Tags: MacOS X, gcc, AltiVec, firefox
張貼留言