【问题标题】:what is this loop optimization called and how does it work?这个循环优化叫什么,它是如何工作的?
【发布时间】:2018-08-07 08:58:57
【问题描述】:

我正在编译以下代码:

#include <stdio.h>
#include <string.h>

int main()
{
  char data[1024];
  scanf("%s", data);

  for (int i = 0; i < strlen(data); i++)
  {
    if (data[i] == 'a')
    {
      printf("%d.\n", i);
    }
  }
}

我正在对 GCC 使用 -O2 优化级别。当检查 gdb 如何在汇编级别完成内部循环时,我在 scanf 之后得到以下指令:

0x40055c:   48 89 e0    mov    %rsp,%rax

然后是迭代的代码:

0x40055f <main+47>      mov    (%rax),%ecx 
0x400561 <main+49>      add    $0x4,%rax
0x400565 <main+53>      lea    -0x1010101(%rcx),%edx
0x40056b <main+59>      not    %ecx
0x40056d <main+61>      and    %ecx,%edx
0x40056f <main+63>      and    $0x80808080,%edx
0x400575 <main+69>      je     0x40055f <main+47> 

我就是想问一下,这个优化怎么叫?所以我可以阅读它,而不是尝试对汇编代码的工作方式进行逆向工程。

附:我理解这个想法是一次移动 4 个字节而不是一个,所以它必须做更少的迭代,但是它是如何调用的以及它是如何工作的?

【问题讨论】:

    标签: algorithm loops gcc optimization


    【解决方案1】:

    需要明确的是,这是 strlen,而不是您的循环。

    这是基于 SWAR word-contains-zero-byte 技巧的优化,在其他地方发现 here

    #define haszero(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL)
    

    由于strlen是一个内在函数,这可能不是任何著名的“命名优化”引起的,它是针对特定函数的特定技巧。

    【讨论】:

    • 非常感谢!正是我正在寻找的。​​span>
    【解决方案2】:

    您显示的汇编代码是strlen() 的一部分,实际上一次移动了 4 个字节,在本例中是为了找到零字节。

    有关算法的实现示例,请参阅this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-24
      • 2015-10-19
      • 2011-05-30
      • 2015-07-25
      • 2015-02-03
      • 2019-03-21
      • 1970-01-01
      相关资源
      最近更新 更多