环路地址对齐如何影响Intel x86_64的速度?

我发现相同的C ++代码的性能降低了15%,这些代码编译为完全相同的机器指令但位于不同对齐的地址上。当我的微小主循环从0x415220开始时,它比在0x415250时更快。我在Intel Core2 Duo上运行它。我在x86_64 Ubuntu上使用gcc 4.4.5。 任何人都可以解释减速的原因以及如何强制gcc最佳地对齐循环? 以下是具有探查器注释的两种情况的反汇编:   415220 576 12.56%| XXXXXXXXXXXXXX 48 c1 eb 08 shr $ 0x8,%rbx   415224 110 2.40%| XX 0f b6 c3 movzbl%bl,%eax   415227 0.00%| 41 0f b6 04 00 movzbl(%r8,%rax,1),%eax   41522c 40 0.87%| 48 8b 04 c1 mov(%rcx,%rax,8),%rax   415230 806 17.58%| XXXXXXXXXXXXXXXXXXX 4c 63 f8 movslq%eax,%r15   415233 186 4.06%| XXXX 48 c1 e8 20 shr $ 0x20,%rax   415237 102 2.22%| XX 4c 01 f9 add%r15,%rcx   41523a 414 9.03%| XXXXXXXXXX a8 0f test $ 0xf,%al   41523c 680 14.83%| XXXXXXXXXXXXXXXX 74 45 je 415283 ::运行(char const *,char const *)+ 0x4b3>   41523e 0.00%| 41 89 c7 mov%eax,%r15d   415241 0.00%| 41 83 e7 01和$ 0x1,%r15d   415245 0.00%| 41 83 ff 01 cmp $ 0x1,%r15d   415249 0.00%| 41 89 c7 mov%eax,%r15d   415250 679 13.05%| XXXXXXXXXXXXXXXX 48 c1 eb 08 shr $ 0x8,%rbx   415254 124 2.38%| XX 0f b6 c3 movzbl%bl,%eax   415257 0.00%| 41 0f b6 04 00 movzbl(%r8,%rax,1),%eax   41525c 43 0.83%| X 48 8b 04 c1 mov(%rcx,%rax,8),%rax   415260 828 15.91%| XXXXXXXXXXXXXXXXXXX 4c 63 f8 movslq%eax,%r15   415263 388 7.46%| XXXXXXXXX 48 c1 e8 20 shr $ 0x20,%rax   415267 141 2.71%| XXX 4c 01 f9 add%r15,%rcx   41526a 634 12.18%| XXXXXXXXXXXXXXX a8 0f test $ 0xf,%al   41526c 749 14.39%| XXXXXXXXXXXXXXXXXX 74 45 je 4152b3 ::运行(char const *,char const *)+ 0x4c3>   41526e 0.00%| 41 89 c7 mov%eax,%r15d   415271 0.00%| 41 83 e7 01和$ 0x1,%r15d   415275 0.00%| 41 83 ff 01 cmp $ 0x1,%r15d   415279 0.00%| 41 89 c7 mov%eax,%r15d     
已邀请:
Gcc有一个-falign-loops = n选项,其中n是要跳过的最大字节数,如果省略则将使用机器默认值。 Gcc在-O2和-O3优化级别自动启用此功能。     
在具有循环流检测的英特尔CPU上,循环体代码对齐可以提高效率,特别是在正常的展开水平下。 首次从顶部进入循环时,对齐会受到惩罚。 你没有在那里显示代码,在对齐的情况下会有一些荒谬的美化无操作指令。 gcc通常使用条件对齐,仅在需要有限数量的填充的情况下才应用对齐。当我查看一次时,影响此行为的选项似乎不太有效。正如亚历山大所说,为-march或-mtune设置一个值非常重要,这样gcc就可以使用相关的对齐设置。 我使用的所有编译器都无法在某些情况下对齐循环体,并且似乎无法控制它。     

要回复问题请先登录注册