如何使用GCC对C语言for循环体进行对齐?

15
在我们的嵌入式架构中,我们有一个64位IAB(指令对齐缓冲区)。为了优化获取序列,需要循环体从8字节边界开始对齐。
在汇编语言中,使用“.balign”指令很容易实现这一点,但我找不到一种语法来提示C编译器对代码进行对齐。
尝试通过带有“.balign”指令的内联汇编来先于for循环,但这样做会对for循环的前导部分(设置)进行对齐,而不是循环体本身。
将“asm()”行放在循环体内部并进行相同操作会向循环体添加成本昂贵的“nop”指令。
编辑1:假设代码如下:
    __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];
    }

我想让第一个 c=a+b 对齐到8字节地址。我可以在初步编译后像上面那样添加 nop 以实现对齐,但这是一种临时解决方案,会随着第一次代码更改而失效。

编辑2: 多亏了@R..,解决方法是使用 -falign-loops=8 编译器选项。


因此,实质上,您希望使用nop使循环主体对齐,但是您希望这些nop在循环前导之前执行? - ruakh
@ruakh - 是的,虽然我不关心nop是否在prolog本身中生成,只要循环末尾的分支指令指向对齐的内存位置即可。 - ysap
4
这不是GCC的-falign-loops选项的作用吗? - R.. GitHub STOP HELPING ICE
@R.. - 这似乎是个妙招!请把它变成一个答案,这样我就可以点赞并接受它了。 - ysap
@R.. - 我真的不知道。我在这里为这个问题打开了一个新的问题 - http://stackoverflow.com/q/9881002/274579 - ysap
显示剩余3条评论
1个回答

5
嗯,这不是GCC的-falign-loops选项的作用吗?

2
是的,但如果您只想影响单个循环,GCC 有任何解决方案吗? - Kristian Spangsege
1
对于单个函数,您可以使用#pragma GCC optimize或等效的属性。但是我不知道是否可以在单个循环级别上执行此操作。如果没有其他方法,您可能可以通过将循环放入嵌套函数中并将属性放在嵌套函数上来实现这一可怕的黑客行为...? - R.. GitHub STOP HELPING ICE
1
针对单个功能进行优化仍然比整个项目的选项更好,因为它在某些情况下(热循环)可能很好,在其他情况下(稀有循环)可能很糟糕。不幸的是,我的测试中无论是#pragma GCC optimize "align-loops = xx"还是__attribute __((optimize("align-loops = xx")))都没有产生任何效果(生成的二进制文件上相同的md5sum)。 - Cyan
相关GCC请求:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67435 - rsaxvc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接