gpt4 book ai didi

c++ - GCC 有时不内联 std::array::operator[]

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:42:54 24 4
gpt4 key购买 nike

我有一个使用 std::array<double, N> 的复杂程序对于 N 的小值。它使用 operator[]从这些数组中获取值。

我发现 GCC 6.1 带有 -O2-O3不内联这些调用,导致这些 C++ 数组比它们的 C 等效数组慢。

这是生成的程序集:

340 <std::array<double, 8ul>::operator[](unsigned long) const>:

340: 48 8d 04 f7 lea (%rdi,%rsi,8),%rax
344: c3 retq
345: 90 nop
346: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
34d: 00 00 00

为每种大小的数组发出完全相同的代码(因为没有边界检查)。

这样一个数组的循环看起来像这样:

4c0:  e8 7b fe ff ff          callq  340 <std::array<double, 8ul>::operator[](unsigned long) const>
4c5: be 07 00 00 00 mov $0x7,%esi
4ca: 4c 89 f7 mov %r14,%rdi
4cd: 48 89 44 24 78 mov %rax,0x78(%rsp)

...6 more copies of this...

4d2: e8 69 fe ff ff callq 340 <std::array<double, 8ul>::operator[](unsigned long) const>
4d7: 48 89 44 24 70 mov %rax,0x70(%rsp)
4dc: 31 f6 xor %esi,%esi
4de: 4c 89 ef mov %r13,%rdi

这显然很糟糕。问题是小型测试程序不会引发这种行为。

所以我的问题是:我怎样才能让 GCC 告诉我为什么它不内联这些单指令调用,和/或让它内联它们?显然我不能修改 <array>要添加的头文件 __attribute__((inline)) .

最佳答案

在使用 __attribute__(("unroll-loops")) 时,GCC 5 和 6 的优化器中似乎存在一个错误。结合 -ffast-math或相关选项。

您可以在此处查看实际效果:https://godbolt.org/g/ZBGCDB

如果您使用 -O3 -ffast-math 编译,此代码会重现错误:

#include <array>

typedef std::array<double, 2> Array;

void foo(Array& a) __attribute__((optimize("unroll-loops")));

void foo(Array& a)
{
for (size_t ii = 0; ii < a.size(); ++ii)
a[ii] = 1.0;
}

它在没有 -ffast-math 的情况下按预期工作,或者如果使用 GCC 4.9、GCC 7 或更高版本或 Clang 编译。

关于c++ - GCC 有时不内联 std::array::operator[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42263537/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com