循环地址对齐如何影响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

下一篇: Performance optimization strategies of last resort