我正在尝试使用4向循环展开来优化此c代码

时间:2009-10-01 05:42:01

标签: c

我正在尝试做的是使用这个C代码并使用称为循环展开的技术对其进行优化,但在这种情况下我想使用四向循环展开。现在,我理解了这项技术,并且我理解了我不知道如何将其应用于此代码的概念。我是否需要添加一些额外的变量?在每个循环之后或者只是在所有循环结束时,我是否必须有一些代码?此代码是8x8块代码,用于处理像素并逆时针旋转90度。任何帮助将不胜感激。谢谢。

/* 
 * 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)];
}

4 个答案:

答案 0 :(得分:5)

您可以使用8行显式代码替换内部循环

          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 x 8行代码,依此类推。

除了理解练习之外,这对我来说似乎毫无意义,编译器非常有效地完成这些工作,他们会在合理的地方进行优化。手动滚动很少产生最佳代码。

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

...吸取的经验教训:始终剖析: - )

答案 2 :(得分:3)

gcc -funrull-loops

你不应该自己展开循环,除非GCC不能这样做(查看程序集)并且你已经通过使用分析器证明你必须加速这部分代码。

您拥有的示例代码看起来是自动循环展开的理想选择。

其他一些有用的标志:

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

答案 3 :(得分:0)

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

如果您的编译器无法优化算法的人类可读,可维护版本,并且您必须加倍作为人类编译器 - 购买新的编译器!没人能买得起人类编制者了。所以,请怜悯自己和你的程序员,他们必须查看你的代码。