Lambda 与手动内联代码更改 GCC 的优化器行为

Joa*_*ñoz 5 c++ optimization lambda gcc

以下代码:

#include <vector>

extern std::vector<int> rng;

int main()
{
  auto is_even=[](int x){return x%2==0;};
  int res=0;
  for(int x:rng){
    if(is_even(x))res+=x;
  }

  return res;
}
Run Code Online (Sandbox Code Playgroud)

由 GCC 11.1(链接到 Godbolt)以一种非常不同的方式优化:

#include <vector>

extern std::vector<int> rng;

int main()
{
  int res=0;
  for(int x:rng){
    if(x%2==0)res+=x;
  }

return res;
}
Run Code Online (Sandbox Code Playgroud)

链接到 Godbolt。)此外,第二个版本(其中 lambda 已被直接手动注入其主体代替调用),比第一个版本快得多。

这是 GCC 错误吗?

Ayx*_*xan 2

这是代码生成的一个怪癖。没有理由不应该对 lambda 版本进行矢量化。事实上,clang按原样对其进行矢量化。如果将返回类型指定为intGCC也会对其进行向量化:

auto is_even = [](int x) -> int { return x % 2 == 0; };
Run Code Online (Sandbox Code Playgroud)

如果您使用std::accumulate,它也是矢量化的。您可以向 GCC 报告此问题,以便他们修复。