为什么叮当使我的简单阶乘函数过于复杂

Why is clang over-complicating my simple factorial function?

本文关键字:于复杂 复杂 函数 叮当 我的 简单 阶乘 为什么      更新时间:2023-10-16

考虑一个简单的阶乘函数:

static int factorial(int n) {
    if (n <= 0) return 1;
    return n * factorial(n - 1);
}
int main(int argc, char** argv) {
    return factorial(argc);
}

使用 -O2 进行编译会产生一个非常有趣的差异:

  • g++ 7.3:我用 10 条左右的指令将几乎相同的循环结构转换为汇编。
  • clang++ 5.0.0:我得到了一大堆220+指令,我不知道发生了什么。

请参阅此处的比较(编译器资源管理器(

在本地构建并比较运行时,简单的 g++ 二进制文件对于 Ubuntu 17.10 上合理范围内的所有值(即不会导致溢出(肯定会运行得更快。

谁能告诉我为什么 clang 会遇到所有这些麻烦,以及它试图做什么(并且在大小和速度上都失败了(?

谁能告诉我为什么 clang 会遇到所有这些麻烦,以及它试图做什么(并且在大小和速度上都失败了(?

它试图通过矢量化代码来最大限度地减少测试和分支操作的数量。

它肯定在尺寸上失败了。至于它是否在速度上失败,你有没有基准测试过?

如果您将命令行选项添加到 -ftree-vectorize ,GCC 将执行相同的操作。