#c #windows #cmake #linker #mingw-w64
#c #Windows #cmake #компоновщик #mingw-w64
Вопрос:
Как я могу ускорить чрезвычайно медленную компиляцию / компоновку C в MinGW-w64 на C ?
Компиляция тривиальной программы «Hello World»:
#include <iostream>
int main()
{
std::cout << "hello world" << std::endl;
}
…занимает 3 минуты(!) на этом компьютере с Windows 10 без загрузки (i7-6700, 32 ГБ оперативной памяти, приличный SSD SATA).:
> ptime.exe g main.cpp
ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <jberkes@pc-tools.net>
=== g main.cpp ===
Execution time: 180.488 s
Process Explorer показывает, что g
дерево процессов заканчивается в ld.exe
, которое не использует какой-либо заметный процессор или ввод-вывод в течение всего времени.
Запуск g
дерева процессов через API Monitor показывает, что в системе есть три необычно длинных системных вызова ld.exe
: два NtCreateFile()
s и a NtOpenFile()
, каждый из которых работает с a.exe
и занимает по 60 секунд каждый.
Замедление происходит только при использовании a.exe
выходных данных по умолчанию; g -o foo.exe main.cpp
занимает максимум 2 секунды.
«Тогда не используйте a.exe
в качестве выходного имени!» на самом деле не является решением, поскольку такое поведение приводит к тому, что CMake тратит много времени на обнаружение функций компилятора.
Версии набора инструментов GCC:
>g --version
g (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
>ld --version
GNU ld (GNU Binutils) 2.30
Комментарии:
1. Я подумал, что, возможно, у вас есть ваша папка через общий сетевой ресурс, но, как сказал @genpfault, это может быть проблема с AV, больше похоже на это. Я бы сказал: а) попробуйте запустить Windows в безопасном режиме. б) Попробуйте выполнить компиляцию в папке ramdrive (я делаю теневую сборку на ramdrive, чтобы ускорить большую компиляцию). c) Что произойдет, если вы скомпилируете в foo.exe а затем переименовать в a.exe или скопировать в a.exe ? Это занимает так много времени?
Ответ №1:
Учитывая, что я не смог воспроизвести проблему на чистой виртуальной машине Windows 10, а зависимость от выходного имени файла привела меня к вмешательству антивируса / вредоносного ПО.
fltmc instances
перечислены несколько возможных драйверов фильтра файловой системы; guess-n-check сузил список до двух из Carbon Black: carbonblackk
amp; ParityDriver
.
Использование Regedit для их отключения с помощью установки Start
значения 0x4
(«Отключено», 0x2
== Автоматически, 0x3
== Вручную) в этих двух разделах реестра с последующей перезагрузкой исправило медлительность:
- HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicescarbonblackk
- HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesParityDriver
Ответ №2:
Чтобы устранить проблему с медленным компонованием, вы можете использовать альтернативный компоновщик.
Мы ускорили наши действия на GitHub, добавив эту опцию компоновщика -fuse-ld=lld
-fuse-ld=lld
будет использоваться компоновщик llvm.
ПРИМЕР:
run: cmake -S. -B build -G "Ninja"
env:
LDFLAGS: "-fuse-ld=lld" # MINGW linking is very slow. Use llvm linker instead.
Документация для LDFLAGS
:
CMake будет использоваться только в первой конфигурации для определения флагов компоновщика по умолчанию, после чего значение LDFLAGS сохраняется в кэше как CMAKE_EXE_LINKER_FLAGS_INIT, CMAKE_SHARED_LINKER_FLAGS_INIT и CMAKE_MODULE_LINKER_FLAGS_INIT. При любом запуске конфигурации (включая первый) переменная среды будет игнорироваться, если определена эквивалентная переменная CMAKE_<TYPE>_LINKER_FLAGS_INIT.