There appears to be a related bug report, Bug 59659 - large zero-initialized std::array compile time excessive https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59659. It was considered "fixed" for 4.9.0, so I consider this testcase either a regression or an edgecase not covered by the patch. For what it's worth, two of the bug report's test cases1 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59659#c6, 2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59659#c2 exhibit symptoms for me on both GCC 4.9.0 as well as 5.3.1
还有两个相关的错误报告:
Bug 68203 - 带有 -std=c++11 的嵌套数组对的结构的无限编译时间 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68203
安德鲁·平斯基 2015-11-04 07:56:57 UTC
这很可能是一个占用内存的问题,它会生成大量默认值
构造函数而不是对它们进行循环。
那个声称是这个的复制品:
Bug 56671 - Gcc 使用大量内存和处理器能力以及大型 C++11 位集 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56671
乔纳森·韦克利 2016-01-26 15:12:27 UTC
为此 constexpr 构造函数生成数组初始化是
问题:
constexpr _Base_bitset(unsigned long long __val) noexcept
: _M_w{ _WordT(__val)
} { }
事实上,如果我们将其更改为S a[4096] {};
我们不明白这个问题。
Using perf
我们可以看到 GCC 大部分时间都花在哪里。第一的:
perf record g++ -std=c++11 -O2 test.cpp
Then perf report
:
10.33% cc1plus cc1plus [.] get_ref_base_and_extent
6.36% cc1plus cc1plus [.] memrefs_conflict_p
6.25% cc1plus cc1plus [.] vn_reference_lookup_2
6.16% cc1plus cc1plus [.] exp_equiv_p
5.99% cc1plus cc1plus [.] walk_non_aliased_vuses
5.02% cc1plus cc1plus [.] find_base_term
4.98% cc1plus cc1plus [.] invalidate
4.73% cc1plus cc1plus [.] write_dependence_p
4.68% cc1plus cc1plus [.] estimate_calls_size_and_time
4.11% cc1plus cc1plus [.] ix86_find_base_term
3.41% cc1plus cc1plus [.] rtx_equal_p
2.87% cc1plus cc1plus [.] cse_insn
2.77% cc1plus cc1plus [.] record_store
2.66% cc1plus cc1plus [.] vn_reference_eq
2.48% cc1plus cc1plus [.] operand_equal_p
1.21% cc1plus cc1plus [.] integer_zerop
1.00% cc1plus cc1plus [.] base_alias_check
除了 GCC 开发人员之外,这对任何人来说都没有多大意义,但看看是什么占用了如此多的编译时间仍然很有趣。
Clang 3.7.0 在这方面比 GCC 做得更好。在-O2
编译所需时间不到一秒,生成一个小得多的可执行文件(8960 字节)和此程序集:
0000000000400810 <main>:
400810: 53 push rbx
400811: 48 81 ec 00 40 00 00 sub rsp,0x4000
400818: 48 8d 3c 24 lea rdi,[rsp]
40081c: 31 db xor ebx,ebx
40081e: 31 f6 xor esi,esi
400820: ba 00 40 00 00 mov edx,0x4000
400825: e8 56 fe ff ff call 400680 <memset@plt>
40082a: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0]
400830: f3 0f 10 04 1c movss xmm0,DWORD PTR [rsp+rbx*1]
400835: f3 0f 5a c0 cvtss2sd xmm0,xmm0
400839: bf 60 10 60 00 mov edi,0x601060
40083e: e8 9d fe ff ff call 4006e0 <_ZNSo9_M_insertIdEERSoT_@plt>
400843: 48 83 c3 04 add rbx,0x4
400847: 48 81 fb 00 40 00 00 cmp rbx,0x4000
40084e: 75 e0 jne 400830 <main+0x20>
400850: 31 c0 xor eax,eax
400852: 48 81 c4 00 40 00 00 add rsp,0x4000
400859: 5b pop rbx
40085a: c3 ret
40085b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
另一方面,使用 GCC 5.3.1,在没有优化的情况下,编译速度非常快,但仍然生成 95328 大小的可执行文件。编译用-O2
将可执行文件大小减少到 53912,但编译时间需要 4 秒。我会确实将此报告给他们的 bugzilla。