2009-10-01 66 views
2

我想要做的是採取這個C代碼,並使用一種稱爲循環展開的技術進行優化,但在這種情況下,我想使用四維循環,雙向循環展開。現在,我理解了這一技術,並理解了我只是不知道如何將其應用於此代碼的概念。我必須添加一些額外的變量嗎?每次循環後還是僅在所有循環結束時都必須有一些代碼?這個代碼是8x8塊代碼,處理像素並將其旋轉90度計數器時鐘。任何幫助將不勝感激。謝謝。我想優化這個C代碼使用4路循環展開

/* 
* rotate8 - rotate with 8x8 blocking 
*/ 

char rotate8_descr[] = "rotate8: rotate with 8x8 blocking"; 

void rotate8(int dim, pixel *src, pixel *dst) 
{ 

int i, j, ii, jj; 

for(ii = 0; ii < dim; ii += 8) 
     for(jj = 0; jj < dim; jj += 8) 
       for (i = ii; i < ii + 8; i++) 
        for (j = jj; j < jj + 8; j++) 
         dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)]; 
} 
+0

你可能想修復語法突出顯示 – Amro 2009-10-01 05:43:52

+3

你是否分析過這個並確定它是一個問題? – GManNickG 2009-10-01 05:48:21

+1

此外,請考慮使用更多的描述性名稱,如「頂部,底部,左側,右側」,而不是「i,ii,j,jj」。很難閱讀。 – GManNickG 2009-10-01 05:49:24

回答

5

您可以通過書面形式明確對每個需要值符合的代碼

  dst[RIDX(dim-1-jj, i, dim)] = src[RIDX(i, jj, dim)]; 
      dst[RIDX(dim-1-(jj+1), i, dim)] = src[RIDX(i, (jj+1), dim)]; 
      ... 
      dst[RIDX(dim-1-(jj+7), i, dim)] = src[RIDX(i, (jj+7), dim)]; 

所以要更換循環變量8條顯性線代替內環。

現在您可以對下一個循環的8個值重複該操作,您將擁有8 x 8行代碼,依此類推。

除了理解練習之外,這對我來說似乎毫無意義,編譯器確實有效地完成了這種工作,他們將優化它的合理位置。手滾動很少產生最佳代碼。

+1

+1我推薦OP配置他的代碼並查看瓶頸位置,然後反彙編他的代碼,看看編譯器如何處理瓶頸。 – 2009-10-01 05:55:10

3
 
gcc -funrull-loops 

你不應該把自己展開循環,除非GCC不能做到這一點(看裝配),你已經使用,你必須加快這部分代碼探查證實。

該示例代碼看起來非常適合自動循環展開。

其他一些有用的標誌:

 
-O3       // turns on a lot of optimizations (almost all) 
-ftree-vectorize -msse2  // vectorizes automatically some loops 
+0

+1 for -ftree-vectorize和-msse2 – LiraNuna 2009-10-02 00:18:36

4

我想說簡介 - 但後來我這樣做我自己。 令人驚訝的部分是 - 內部循環的執行速度與您的 佈局相同 - 手動展開其實際速度較慢。

但是 - 真正的問題是RIDX宏。切換存儲器佈局和切換外環具有顯着的影響。

這是我用縮進的最快版本,顯示它與您的版本不同的地方。 RIDX宏被假定爲定義。

#define RIDX(x,y,d) (x+(y)*(d)) 
typedef unsigned char pixel; 
void rotate8(int dim, pixel *src, pixel *dst) 
{ 
    int i, j, ii, jj; 
     for(jj = 0; jj < dim; jj += 8) 
    for(ii = 0; ii < dim; ii += 8) 
       for (i = ii; i < ii + 8; i++) 
        for (j = jj; j < jj + 8; j++) 
         dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)]; 
} 

...教訓:永遠輪廓:-)

0

http://www.relisoft.com/book/lang/pointer/2ptrarr.html

如果你的編譯器無法優化算法的人類可讀,可維護的版本,你必須兼作一個人類編譯器 - 購買一個新的編譯器!沒有人能夠再買得起人力編制者。所以,要憐憫你自己和你的程序員,他們必須看你的代碼。