2015-05-31 74 views
0

我在展開嵌套for循環時遇到問題。我理解這個概念,我試圖將其付諸實踐,但是我正在編輯我的for循環中的語句,以適應展開過程,因此絆倒了我。展開嵌套for循環 - C

如果有人能夠向我展示一個有效的展開,並讓我通過它,這將是一個巨大的幫助。

這裏是環部分,我想展開:

for (i=1 ; i < WIDTH-1 ; ++i) 
{ 
     for (j = 1 ; j < HEIGHT-1 ; ++j) 
     { 
     n = getNeighbors(prv, i, j); /* This is where I'm confused */ 
     mask = (prev[i][j] << 1);  
     next[i][j] = !(((n >> prev[i][j])^3)^mask); 
     } 
} 

UPDATE: 這會是正確的嗎?

for (i=1 ; i < WIDTH-1 ; i+=4) 
{ 
     for (j = 1 ; j < HEIGHT-1 ; j+=4) 
     { 
     n = getNeighbors(prv, i, j); 
     mask = (prev[i][j] << 1);  
     next[i][j] = !(((n >> prev[i][j])^3)^mask); 
     n = getNeighbors(prv, i, j+1); 
     mask = (prev[i][j+1] << 1);  
     next[i][j+1] = !(((n >> prev[i][j+1])^3)^mask); 
     n = getNeighbors(prv, i, j+2); 
     mask = (prev[i][j+2] << 1);  
     next[i][j+2] = !(((n >> prev[i][j+2])^3)^mask); 
     n = getNeighbors(prv, i, j+3); 
     mask = (prev[i][j+3] << 1);  
     next[i][j+3] = !(((n >> prev[i][j+3])^3)^mask); 
     } 
     for (j = 1 ; j < HEIGHT-1 ; j+=4) 
     { 
     n = getNeighbors(prv, i+1, j); 
     mask = (prev[i+1][j] << 1);  
     next[i+1][j] = !(((n >> prev[i+1][j])^3)^mask); 
     n = getNeighbors(prv, i+1, j+1); 
     mask = (prev[i+!][j+1] << 1);  
     next[i+1][j+1] = !(((n >> prev[i+1][j+1])^3)^mask); 
     n = getNeighbors(prv, i+1, j+2); 
     mask = (prev[i+1][j+2] << 1);  
     next[i+1][j+2] = !(((n >> prev[i+1][j+2])^3)^mask); 
     n = getNeighbors(prv, i+1, j+3); 
     mask = (prev[i+1][j+3] << 1);  
     next[i+1][j+3] = !(((n >> prev[i+1][j+3])^3)^mask); 
     } 
     for (j = 1 ; j < HEIGHT-1 ; j+=4) 
     { 
     n = getNeighbors(prv, i+2, j); 
     mask = (prev[i+2][j] << 1);  
     next[i+2][j] = !(((n >> prev[i+2][j])^3)^mask); 
     n = getNeighbors(prv, i+2, j+1); 
     mask = (prev[i+2][j+1] << 1);  
     next[i+2][j+1] = !(((n >> prev[i+2][j+1])^3)^mask); 
     n = getNeighbors(prv, i+2, j+2); 
     mask = (prev[i+2][j+2] << 1);  
     next[i+2][j+2] = !(((n >> prev[i+2][j+2])^3)^mask); 
     n = getNeighbors(prv, i+2, j+3); 
     mask = (prev[i+2][j+3] << 1);  
     next[i+2][j+3] = !(((n >> prev[i+2][j+3])^3)^mask); 
     } 
     for (j = 1 ; j < HEIGHT-1 ; j+=4) 
     { 
     n = getNeighbors(prv, i+3, j); 
     mask = (prev[i+3][j] << 1);  
     next[i+3][j] = !(((n >> prev[i+3][j])^3)^mask); 
     n = getNeighbors(prv, i+3, j+1); 
     mask = (prev[i][j+1] << 1);  
     next[i+3][j+1] = !(((n >> prev[i+3][j+1])^3)^mask); 
     n = getNeighbors(prv, i+3, j+2); 
     mask = (prev[i][j+2] << 1);  
     next[i+3][j+2] = !(((n >> prev[i+3][j+2])^3)^mask); 
     n = getNeighbors(prv, i+3, j+3); 
     mask = (prev[i+3][j+3] << 1);  
     next[i+3][j+3] = !(((n >> prev[i+3][j+3])^3)^mask); 
     } 
} 
+0

什麼是'prv'?你試圖通過展開循環來實現什麼?你終於想要一個單一的循環或根本沒有循環? –

+3

爲什麼不讓編譯器負責爲您展開循環? –

+0

WIDTH和HEIGHT常量?這些值需要展開。 – QuentinUK

回答

0

讓循環是:

for(int i = 0; i < x; ++i) 
    for(int j = 0; j < y; ++j) 
     dosomething(i, j); 

可以展開如下:

for(int i = 0; i < x; i += 4) { 
    for(int j = 0; j < y; j += 4) { 
     dosomething(i, j); 
     dosomething(i, j + 1); 
     dosomething(i, j + 2); 
     dosomething(i, j + 3); 
    } 
    for(int j = 0; j < y; j += 4) { 
     dosomething(i + 1, j); 
     dosomething(i + 1, j + 1); 
     dosomething(i + 1, j + 2); 
     dosomething(i + 1, j + 3); 
    } 
    for(int j = 0; j < y; j += 4) { 
     dosomething(i + 2, j); 
     dosomething(i + 2, j + 1); 
     dosomething(i + 2, j + 2); 
     dosomething(i + 2, j + 3); 
    } 
    for(int j = 0; j < y; j += 4) { 
     dosomething(i + 3, j); 
     dosomething(i + 3, j + 1); 
     dosomething(i + 3, j + 2); 
     dosomething(i + 3, j + 3); 
    } 
} 

不知道有多少好處將這個有。你應該在展開後分析你的代碼。

+0

感謝您的評論。如果我在循環中有多個語句,比如我在代碼中的3個任務,那麼我將如何構造它?我假設我會這樣做,就像你在評論中展示我的方式一樣,每個任務都完成了(例如)4次+ 1,+ 2,+ 3 – slippeel

+0

這種展開只有在'x'和'y'已知是「4」的倍數。展開外部循環比展開內部循環要有用得多。 – chqrlie

0

只是一個例子:

int r[3][3]; 

// loop version 
for (int i = 0; i < 3; i++) { 
    for (int j = 0; j < 3; j++) { 
     r[i][j] = i + j; 
    } 
} 

// unrolled version 
r[0][0] = 0; 
r[0][1] = 1; 
r[0][2] = 2; 
r[1][0] = 1; 
r[1][1] = 2; 
r[1][2] = 3; 
r[2][0] = 2; 
r[2][1] = 3; 
r[2][2] = 4; 

請注意,這種完全攤很容易可以只對向量或矩陣,其大小在編譯時是已知的。另請注意,最近的編譯器通常能夠自行展開這樣的循環。