展开嵌套for循环 - C.

时间:2015-05-31 18:07:35

标签: c loop-unrolling

我在展开嵌套的for循环时遇到问题。我理解这个概念,我正在尝试将其付诸实践,但是我在编辑我的for循环中的语句时遇到了与展开相匹配的问题。

如果有人能够向我展示一个有效的展开并引导我完成它,这将是一个巨大的帮助。

以下是我要展开的循环部分:

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);
      }
}

更新: 这是正确的吗?

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);
      }
}

2 个答案:

答案 0 :(得分: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);
    }
}

不确定这会带来多少好处。您应该在展开后对您的代码进行分析。

答案 1 :(得分: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;

请注意,只有在编译时已知大小的向量或矩阵才能轻松完成这种完全展开。还请注意,最近的编译器通常能够自行展开这样的循环。