Ускорить чрезвычайно медленную компиляцию / связывание MinGW-w64?

#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.