Ответ 1
Похоже, что есть связанный отчет об ошибке, Ошибка 59659 - избыточное время компиляции большого значения с нулевым инициализированным значением std:: array. Он считался "фиксированным" для 4.9.0, поэтому я рассматриваю этот тест либо регрессию, либо edgecase, не охватываемую патчем. Для чего стоит, два тестовых примера отчета об ошибках 1, 2 проявляют симптомы для меня как на GCC 4.9.0, так и на 5.3.1
Есть еще два связанных отчета об ошибках:
Ошибка 68203 - бесконечное время компиляции на struct с вложенным массивом пар с -std = С++ 11
Эндрю Пински 2015-11-04 07:56:57 UTC
Это, скорее всего, паук памяти, который генерирует множество параметров по умолчанию конструкторы, а не петлю над ними.
Тот, кто утверждает, является дубликатом этого:
Ошибка 56671 - Gcc использует большие объемы памяти и мощности процессора с большими С++ 11 битами
Джонатан Вакели 2016-01-26 15:12:27 UTC
Генерация инициализации массива для этого конструктора constexpr проблема:
constexpr _Base_bitset(unsigned long long __val) noexcept : _M_w{ _WordT(__val) } { }
Действительно, если мы изменим его на S a[4096] {};
, мы не получим проблемы.
Используя perf
, мы видим, что GCC проводит большую часть своего времени. Во-первыхи:
perf record g++ -std=c++11 -O2 test.cpp
Затем 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 <[email protected]>
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 <[email protected]>
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.