循环地址对齐如何影响Intel x86的速度
我看到相同的C ++代码编译为完全相同的机器指令,但位于不同对齐的地址上的性能下降了15%。 当我的微小主循环从0x415220开始时,它的速度快于0x415250。 我在Intel Core2 Duo上运行这个。 我在x86_64 Ubuntu上使用gcc 4.4.5。
任何人都可以解释放缓的原因,以及我可以如何强制gcc优化对齐循环?
以下是使用Profiler注释对两种情况进行反汇编:
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 ::Run(char const*, char const*)+0x4b3> 41523e 0.00% | 41 89 c7 mov %eax,%r15d 415241 0.00% | 41 83 e7 01 and $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 ::Run(char const*, char const*)+0x4c3> 41526e 0.00% | 41 89 c7 mov %eax,%r15d 415271 0.00% | 41 83 e7 01 and $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优化级别。
在具有循环流检测的Intel CPU上,循环体码对齐可以提高效率,特别是在正常展开级别的情况下。 当第一次从顶部进入循环时,对齐付费。 你没有在那里显示代码,在对齐的情况下会出现一些荒谬的无操作指令。 gcc通常使用条件对齐,仅在需要有限数量的填充的情况下才应用对齐。 当我看了一次,影响这种行为的选项似乎不是很有效。 正如Alexander所说,为-march或-mtune设置一个值是很重要的,以便gcc可以使用相关的对齐设置。 我使用的所有编译器在某些情况下无法对齐循环体,并且似乎没有对此进行控制。
链接地址: http://www.djcxy.com/p/2489.html上一篇: How does loop address alignment affect the speed on Intel x86