Как улучшить производительность ссылок для большого приложения C ++ в VS2005 - PullRequest
24 голосов
/ 27 сентября 2008

У нас есть довольно большое приложение на C ++, которое состоит из около 60 проектов в Visual Studio 2005. В настоящее время соединение в режиме Release занимает 7 минут, и я хотел бы попытаться сократить время. Есть ли какие-либо советы по улучшению времени соединения?

Большинство проектов компилируются в статические библиотеки, это облегчает тестирование, поскольку каждый из них также имеет набор связанных модульных тестов. Похоже, что использование статических библиотек не позволяет VS2005 использовать инкрементную компоновку, поэтому даже при включенной инкрементной компоновке происходит полная ссылка каждый раз.

Будет ли иметь какое-то значение использование DLL для подпроектов? На самом деле я не хочу просматривать все заголовки и добавлять макросы для экспорта символов (даже используя скрипт), но если он что-то сделает, чтобы сократить 7-минутное время соединения, я обязательно его учту.

По какой-то причине использование nmake из командной строки немного быстрее, а связывание того же приложения в Linux (с GCC) - намного быстрее.

  • Visual Studio IDE 7 минут
  • Visual C ++ с использованием nmake из командной строки - 5 минут
  • GCC в Linux 34 секунды

Ответы [ 15 ]

19 голосов
/ 28 сентября 2008

Если вы используете флаг /GL для включения оптимизации всей программы (WPO) или флаг /LTCG для включения генерации временного кода канала, их отключение значительно улучшить время соединения за счет некоторой оптимизации.

Кроме того, если вы используете флаг /Z7 для помещения символов отладки в файлы .obj, ваши статические библиотеки, вероятно, огромны. Использование /Zi для создания отдельных файлов .pdb может помочь, если он не позволяет компоновщику прочитать все символы отладки с диска. Я не уверен, что это действительно помогает, потому что я не тестировал его.

8 голосов
/ 20 ноября 2009

См. Мое предложение, сделанное в Microsoft: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=511300

Вы должны проголосовать за это! Вот мой последний комментарий:

Да, мы используем инкрементные ссылки для создания большинства наших проектов. Для самых больших проектов это бесполезно. На самом деле, требуется больше времени, чтобы связать эти проекты с инкрементным связыванием (2 минуты 50 по сравнению с 2 минутами 44). Мы заметили, что это не работает, когда размер ILK-файлов велик (наш самый большой проект генерирует аналог 262144 КБ в win 32).

Ниже, я перечисляю другие вещи, которые мы пытались сократить время ссылки:

  • Явная реализация шаблона для уменьшения раздувания кода. Небольшой выигрыш.
  • IncrediLink (IncrediBuild дает интересный выигрыш для компиляции, но почти не дает усиления для ссылки).
  • Удалите отладочную информацию для библиотек, которые редко отлаживаются (хороший выигрыш).
  • Удалить файл PDB в «Pre-Build Event» (как ни странно, он дает интересный выигрыш, например: 2min44 вместо 3min34).
  • Преобразование многих статических библиотек в DLL. Важный выигрыш.
  • Работа с компьютером, оснащенным большим количеством оперативной памяти, для максимального увеличения дискового кэша. Самый большой выигрыш.
  • Большой объект против малого объекта. Без разницы.
  • Изменить параметры проекта (/ Ob1, / INCREMENTAL, включить свертывание COMDAT, встраивать манифест и т. Д.). Одни дают интересную выгоду, другие нет. Мы стараемся постоянно максимально использовать наши настройки.
  • Развернуть Внутренняя связь против Внешней связи. Это хорошая практика программирования.
  • Отделяйте программный компонент столько, сколько мы можем себе позволить. Вы можете работать в модульном тесте, что ссылка быстро. Но нам все еще нужно объединить вещи, у нас есть устаревший код, и мы работали со сторонним компонентом.
  • Использовать секретный переключатель компоновщика / ожидаемый размер выхода: 120000000. Небольшой выигрыш.

Обратите внимание, что во всех наших экспериментах мы тщательно измеряли время соединения. Время медленной связи серьезно сказывается на производительности. Когда вы реализуете сложный алгоритм или отслеживаете сложную ошибку, вы хотите быстро повторить эту последовательность: изменить некоторый код, ссылку, отладку трассировки, изменить некоторый код, ссылку и т. Д.

Еще одним моментом оптимизации времени соединения является его влияние на наш непрерывный цикл интеграции. У нас есть много приложений, которые используют общий код, и мы постоянно его интегрируем. Время соединения всех наших приложений заняло половину времени цикла (15 минут) ...

В теме https://blogs.msdn.microsoft.com/vcblog/2009/09/10/linker-throughput/, были сделаны некоторые интересные предложения по улучшению времени ссылки. Почему на 64-битном компьютере нет возможности полностью работать с файлом в оперативной памяти?

Опять же, любые предложения, которые могут помочь нам сократить время ссылки, приветствуются.

5 голосов
/ 27 сентября 2008

Как правило, использование DLL вместо статических библиотек значительно улучшит время компоновки.

4 голосов
/ 27 сентября 2008

Взгляните на Incredibuild от Xoreax. Распределенная компиляция значительно сократила время полной сборки / компоновки с 40 до 8 минут.

Кроме того, этот продукт имеет функцию, которую они называют Incredilink , которая должна помочь вам получить инкрементные ссылки, работающие даже со статически связанными библиотеками.

2 голосов
/ 17 ноября 2009

Для отладочных сборок можно использовать инкрементную компоновку, что может значительно увеличить время компоновки.

К сожалению, есть определенные подводные камни, и VS2005 не предупредит вас.

  • Если используются статические библиотеки, то инкрементное связывание не будет работать при изменении части файла для статической библиотеки. Решение состоит в том, чтобы установить для параметра компоновщика «Использовать входы зависимостей библиотеки» значение «Да» (аналогично Fast Solution Build в VS2003)

  • Если использовать pragma-comment-lib для включения библиотеки DLL и указать относительный путь вместо одной библиотеки, то добавочное связывание перестанет работать. Решение состоит в том, чтобы указать только библиотеку lib и использовать опцию компоновщика LIBPATH для добавления дополнительного пути к библиотеке.

  • Иногда файл .ilk будет поврежден (его размер превысит 200 МБ), а затем внезапно инкрементный компоновщик займет более 10 раз больше обычного времени. Иногда он будет жаловаться на повреждение файла .ilk, но обычно сначала через несколько минут. Решением для меня было настроить следующую команду для «Build Event» -> «Pre-Link Event»

    для %% f in ($ (IntDir) *. Ilk) сделать (если "%% ~ zf" GTR "200000000" (del %% f))

2 голосов
/ 26 октября 2009

Я только что узнал, что мы случайно определили большую таблицу строк в заголовочном файле, которая была включена почти во все (статические) библиотеки. (Я имею в виду огромный проект на C ++.) Когда компоновщик создал EXE-файл, он выглядит как объединение таблицы (в EXE-файле только один файл), или разбор библиотек занял целую вечность. Размещение таблицы в отдельном файле C ++ заняло пару минут ссылки на относительно медленной машине.

К сожалению, я не знаю, как найти такие вещи, кроме как случайно.

2 голосов
/ 28 сентября 2008

Раньше у меня были похожие проблемы при связывании больших приложений с Visual C ++. В моем случае у меня просто не было достаточно свободной оперативной памяти, а чрезмерная подкачка на диск замедляла процесс соединения. Удвоение моей оперативной памяти с 1 ГБ до 2 ГБ значительно улучшилось. Сколько стоит ваша коробка разработчика?

2 голосов
/ 28 сентября 2008

Несколько человек сообщили (и я сам заметил), что изменение файла в статически связанной библиотеке отключит инкрементные ссылки для всего решения; похоже, это то, что вы видите. См. Комментарии здесь и здесь для получения дополнительной информации об этом.

Один из способов - использовать надстройку Fast Solution Build . Это может потребовать внесения нескольких изменений в ваше рабочее пространство, но выигрыш определенно стоит . Для коммерческого решения используйте Xoreax Incredibuild , который в основном включает ту же технологию, но добавляет и другие функции. Я прошу прощения, если я звучу как продавец для Incredibuild - я просто очень довольный клиент.

2 голосов
/ 27 сентября 2008

Я не думаю, что преобразование в DLL было бы полезно. Вы можете попытаться найти варианты, связанные с оптимизацией, и отключить их. Возможно, компоновщик потратил много времени, просматривая библиотеки на предмет избыточного кода, который он может устранить. Ваше приложение может оказаться больше или медленнее, но это не может быть проблемой для вас.

1 голос
/ 22 марта 2012

Шаг 1 в C ++ - сокращение времени сборки - больше памяти. После переключения с 4 ГБ на 12 ГБ, я увидел, как время, в течение которого выполняются все ссылки, падает с обрыва: с 5:50 до 1: 15.

...