CMake на 3,16 порядка медленнее в фазе генерации для Make-файлов по сравнению со старыми версиями - PullRequest
4 голосов
/ 06 февраля 2020

Я консультируюсь с компанией о том, как ускорить их сборки, и я сразу же указал им на предварительно скомпилированные заголовки и сборки для единства - 10-минутная полная сборка может легко упасть до 2-3 минут. К счастью, недавно был выпущен CMake 3.16, и поддерживает оба этих , поэтому я сказал им обновить.

Проблема заключается в следующем: после того, как они переключились с CMake 2.6 на 3.16, потребовалось время для запуска CMake подскочил с 20 секунд до более 10 минут. Большая часть времени проводится в фазе генерации. Он завершается успешно, если вы дали ему достаточно времени, и код успешно скомпилирован с помощью сборок Unity, но это время CMake недопустимо.

Вот их настройка:

  • CMake 2.6, old Стиль CMake с глобальными флагами / определяет / включает - не современный (на основе цели). Ничего особенного - никаких пользовательских команд или правил сборки и сложных зависимостей.
  • используется компилятор G CC 7, и они генерируют Makefile - ОС CentOS 7, ядро: Linux 3.10.0-862.14 .4.el7.x86_64
  • около 2000 .cpp файлов, распределенных по 100 библиотекам и 600 исполняемым файлам (большинство из которых - тестовые исполняемые файлы с одним .cpp в них)
  • большинство .cpp файлы собраны / скопированы с помощью aux_source_directory - мы не знаем, что явное перечисление .cpp файлов является анти-паттерном, но это не имеет значения - я думаю, что это не имеет значения, поскольку это должно происходить в Шаг конфигурации, а не во время генерации, правильно?

Вот что мы наблюдали:

  • мы сделали бинарный поиск по различным версиям CMake и пришли к выводу, что огромное замедление произошло между 3.15 и 3.16 - именно тогда, когда была добавлена ​​поддержка предварительно скомпилированного заголовка и единой сборки, но я не думаю, что эти функции имеют какое-либо отношение к замедлению - Я не могу придумать причину, по которой они оказали такое влияние - это должен быть какой-то другой рефакторинг или изменение ...
  • мы отключили все тесты (это означает, что почти все 600 исполняемых файлов были удалены) - похудение число целей CMake от 700 до чуть более 100 - и время, необходимое для запуска CMake, значительно сократилось, но все же было в пару раз больше, чем с CMake 2.6 для всех 700 целей.
  • we наблюдал за тем, что происходило с использованием strace, и были в основном вызовы lstat и access вместе с некоторыми операциями чтения и записи - но это было бесконечно - казалось сотнями операций в секунду в очень повторяемой манере. Также постоянно была попытка найти libgflags.so, который постоянно терпел неудачу. К сожалению, сейчас у меня нет таких журналов.
  • мы создали профиль callgrind, и вот как он выглядит после пары минут работы: https://i.imgur.com/Z9AObso.png (вывод callgrind) файл можно найти здесь ) - похоже, большую часть времени тратится на ComputeLinkLibs() и получение полного имени и определений целей и еще много чего ... Не слишком ли много 700 целей? Это экспоненциальная проблема? Почему это не проблема с CMake 3.15?

Я не смог найти сообщений о том, что у кого-то есть такая же проблема на inte rnet ... Есть идеи, что попробовать дальше? Возможно профиль с использованием Perf? Попробуйте использовать ниндзя в качестве бэкэнда ( отчет о том, что он быстрее )?

1 Ответ

1 голос
/ 06 февраля 2020

Отличный анализ. Это будет полезно для разработчиков CMake. Но я сомневаюсь, что вы найдете здесь большую помощь. Пожалуйста, откройте выпуск .

Бонусные баллы, если вы можете предоставить минимальный пример, демонстрирующий вашу проблему. Вы можете получить это, создав тонны файлов.

...