2011-09-16 61 views
1

我只是在我們擁有的power6集羣上玩Altivec擴展。我注意到,當我沒有任何優化地編譯下面的代碼時,我的預期速度是4。但是,當我用-O3標誌再次編譯它時,我設法獲得了60的加速!帶有Altivec的IBM xlC編譯器的環路優化

只是想知道是否有人對此有更多的經驗,並且能夠提供一些關於編譯器如何重新編排我的代碼以執行如此加速的見解。通過彙編和指令流水線處理這裏是唯一可能的優化,還是有一些我錯過了,我可以包括在我未來的工作中。

int main(void) { 
     const int m = 1000; 

     __vector signed int va; 
     __vector signed int vb; 
     __vector signed int vc; 
     __vector signed int vd; 

     int a[m]; 
     int b[m]; 
     int c[m]; 

     for(int i=0 ; i < m ; i++) { 
       a[i] = i; 
       b[i] = i; 
       c[i] = 0; 
     } 

     for(int cnt = 0 ; cnt < 10000000 ; cnt++) { 
       vd = (__vector signed int){cnt,cnt,cnt,cnt}; 

       for(int i = 0 ; i < m/4 ; i+=4) { 
         va = vec_ld(0, &a[i]); 
         vb = vec_ld(0, &b[i]); 
         vc = vec_add(vd, vec_add(va,vb)); 
         vec_st(vc, 0, &c[i]); 
       } 
     } 

     std::cout << c[0] << ", " << c[1] << ", " << c[2] << ", " << c[3] << "\n"; 

     return 0; 
} 

回答

4

我已經在Power 7上做了一些工作,而且我看到XLC編譯器很奇怪。但不是這樣奇怪! (至少不是60x ...)

有一點需要注意PowerPC系列(至少對於Power6和Power7),就是指令延遲很長,而亂序執行比較弱到x86/x64。

因此,內循環(寫在你的代碼中)會得到非常低的IPC。

現在,我可以想象你獲得60x加速的唯一方法是內部循環是完全展開在-O3下。這是可能的,因爲內部循環的行程計數可以靜態確定爲63.展開內部循環基本上允許填充整個管道。

當然,我只是猜測。你最好的選擇是看看裝配。

另外,你如何計時?很多怪異的行爲我已經看到了在PowerPC的是定時器自己...

編輯:

由於示例代碼是相當簡單的,它應該是很容易被發現(在裝配)無論內部循環是否部分或完全展開。

+0

我一直只用AIX中的「time」命令來計時。我沒有在代碼中插入任何定時器。另外,我有點困惑,爲什麼有IPC?這項工作不是全部在單個線程和單個核心上完成嗎? – entitledX

+0

對不起,我的意思是IPC「每個週期的指令」。我沒有意識到它也代表每個週期的中斷... :)「時間」命令應該沒問題。在某些情況下,我用clock()看到了怪異。 – Mysticial