【发布时间】:2012-04-10 11:31:58
【问题描述】:
我正在使用这个选项来优化我们嵌入式架构中的 for 循环 (here)。但是,我注意到,当对齐需要添加多个 nop 指令时,编译器会生成一个 nop 后跟尽可能多的零 (0000)。
我怀疑这是我们编译器中的错误,但有人可以确认这不是 GCC 中的错误吗?
这是一个代码sn-p:
__asm__ volatile("nop");
__asm__ volatile("nop");
for (j0=0; j0<N; j0+=4)
{
c[j0+ 0] = a[j0+ 0] + b[j0+ 0];
c[j0+ 1] = a[j0+ 1] + b[j0+ 1];
c[j0+ 2] = a[j0+ 2] + b[j0+ 2];
c[j0+ 3] = a[j0+ 3] + b[j0+ 3];
}
使用-falign-loops=8(或与您的架构相关的任何数字,超过所需的最小对齐)进行编译。您可以根据需要添加或删除 __asm__ 行以生成未对齐的循环体。
【问题讨论】:
-
顺便说一句,我也会摆脱丑陋的手动循环展开,让 gcc 展开循环(默认情况下,它会在认为有意义时使用
-O3执行此操作)。跨度> -
@R.. - 显然,在现实世界中并非如此。这段代码实际上是我进行向量加法的基准的一部分。我有两个函数,带有上述代码的 vecadd() 和类似于您的建议的 vecadd_naive()。事实是我必须手动展开 16 次才能获得最佳性能,这比天真的版本要好一点。这是使用 -O3 和(可能是多余的)-funroll-loops。
-
@R..- 请记住,优化器用于展开循环的启发式方法是基于一些任意的规则集(好的,至少是任意的 w.r.t 可用选项)。您的考虑(例如,代码大小或寄存器使用)可能会有所不同,毕竟会导致更快的代码。我想这就是我看到的不同之处。
-
您可以在循环之前添加
#pragma用于优化级别/展开决策参数,而不是手动展开它。我不确定这是否比自己展开循环更好或更丑陋......
标签: c gcc for-loop alignment memory-alignment