Как улучшить время компиляции Visual С++?

Я компилирую 2 проекта С++ в buildbot, на каждом коммите. Оба файла составляют около 1000 файлов, один - 100 клоков, другой - 170 kloc. Время компиляции сильно отличается от gcc (4.4) до Visual С++ (2008).

Сборники Visual С++ для одного проекта за 20 минут. Они не могут использовать преимущества нескольких ядер, потому что проект зависит от другого. В итоге полная компиляция обоих проектов в Debug и Release в 32 и 64 бит занимает более 2 1/2 часов.

gcc компиляции для одного проекта за 4 минуты. Он может быть распараллелен на 4 ядрах и занимает около 1 мин 10 секунд. Все 8 сборников для 4-х версий (Debug/Release, 32/64 бит) из 2 проектов скомпилированы менее чем за 10 минут.

Что происходит с моментами компиляции Visual С++? Они в основном в 5 раз медленнее.

Каково среднее время, которое можно ожидать для компиляции С++ kloc? Шахта составляет 7 с/клок с vС++ и 1,4 с/клок с gcc.

Можно ли что-то сделать для ускорения времени компиляции на Visual С++?

Ответ 1

Одна вещь, которая замедляет компилятор VС++, заключается в том, что у вас есть заголовочный файл, который инициализирует конкретные экземпляры типов значений, отличных от триангового const. Вы можете видеть, что это происходит с константами типа std::string или GUID. Это влияет как на время компиляции, так и на связь.

Для одной dll это вызвало 10-кратное замедление. Это помогает, если вы помещаете их в предварительно скомпилированный файл заголовка или просто объявляете их в заголовке и инициализируете их в файле cpp.

Посмотрите на антивирусный сканер и не забудьте экспериментировать с предварительно скомпилированными заголовками, без него вы не увидите VС++ в лучшем виде.

О да, и убедитесь, что папка% TMP% находится на том же самом разделе, где написана ваша сборка, поскольку VС++ создает временные файлы и перемещает их позже.

Ответ 2

Проекты, зависящие друг от друга, не подразумевают, что распараллеливание невозможно. Системы построения достаточно умны, чтобы понять и избежать критических зависимостей, иначе gcc не сможет использовать 4 ядра.

Итак (в дополнение к другим шагам), почему бы просто не попробовать включить многопроцессорность в Visual Studio с помощью /MP (см. http://msdn.microsoft.com/en-us/library/bb385193.aspx).

Ответ 3

Как вы строите проекты Visual Studio? Вы просто запускаете ide (devenv) с проектом и /build или у вас есть make файл, аналогичный тому, что я предполагаю, что вы используете для gcc. Я предполагаю, что оба сборщика используют аналогичный make файл, но я думал, что стоит проверить.

Используете ли вы предварительно скомпилированные заголовки для любого компилятора? Если вы НЕ используете предварительно скомпилированные заголовки для VS, вы можете переключиться на их использование. Лично я бы рекомендовал использовать подход #pragma hdrstop, а не один всплывающий заголовочный файл, но если вы в настоящее время НЕ используете предварительно скомпилированные заголовки и хотите попробовать один единственный заголовочный файл с включенным включением (с помощью /FI командной строки коммутатора) можно быстро протестировать без каких-либо изменений кода.

Я написал обо всех /FI и #pragma hdrstop здесь: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html

Ответ 4

Это не прямой ответ на вопрос, но в моей компании мы используем IncrediBuild для распределенной компиляции. Это действительно ускоряет процесс компиляции. http://incredibuild.com/visual_studio.htm

Ответ 5

В книге "Крупномасштабный дизайн программного обеспечения на C++" Джона Лакоса есть много советов по структурированию вашего кода и дизайна для крупномасштабных проектов. Включая множество советов по ускорению компиляции. Не имеет прямого отношения к Visual С++, но стоит все равно прочитать.

Ответ 6

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

Ответ 7

Прежде всего, в большинстве случаев вы можете параллельно строить конфигурации отладки и выпуска одного и того же проекта.

Также то, что вы описываете, звучит ужасно медленно - похоже, что вы не используете предварительно скомпилированные заголовки в VС++ или используете их неправильно - они специально предназначены для улучшения времени компиляции.

Ответ 8

Возможно, есть проблема с проверкой зависимостей, если вы не заставляете полностью перестраивать.

Вы можете создать несколько статических библиотек. Поместите код, который редко изменяется в библиотеках.

Самые медленные части построения программы:

  • Открытие и закрытие файлов.
  • Анализ и перевод исходного кода файлы.

В целом, этапы создания ссылок и исполняемого файла являются самыми быстрыми.

Вы определили:

  • какие фазы являются самыми медленными?
  • Какие файлы наиболее медленны для компиляции?

Помните, что при определении эффективности всегда профиль (тем или иным способом).

Ответ 9

Вы строите на одной машине? Вы используете одну и ту же ОС? Я видел различия в скорости в области 3-10x при сравнении GCC в Cygwin и GCC на машине VirtualBox, работающей внутри Windows, на которой находится Cygwin.

Ответ 10

Кажется очень странным, что будет такая разница... но нет причин, по которым вы не можете использовать мультикоры на Visual!

В основном у вас есть 4 режима компиляции: (Debug/Release) x (32 бит /64 бит), каждый из которых полностью независим от другого, вы можете отлично управлять 4 параллельно, используя в полной мере 4 ядра. Или просто попробуйте использовать метод MultiProcessor в Visual Studio.

Однако это не собирается сокращать его. 150 минут против 10 минут - огромный разрыв. Из моего личного опыта есть 2 основных фактора в сокращении времени компиляции:

  • имеют все файлы, используемые на локальном диске (при необходимости, используя репликацию из удаленных) и все файлы, созданные локально (.o.so)
  • используйте все ядра в вашем распоряжении, и если вы можете, даже перейдите на Multi Machines (distcc и т.д.).

Ответ 11

Компилировать и связывать один файл cpp за раз, даже если изменения заголовка файла влияют на несколько файлов cpp. Это можно выполнить с помощью макроса визуальной студии:

Dim WithEvents myTimer As Timers.Timer

Sub CompileAndLinkCurrentCppFile()
    DTE.ExecuteCommand("Build.Compile")
    myTimer = New Timers.Timer
    myTimer.Interval = 0.05
    myTimer.Start()
End Sub

Sub myTimer_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles myTimer.Elapsed
    If DTE.Solution.SolutionBuild.BuildState <> vsBuildState.vsBuildStateInProgress And DTE.Solution.SolutionBuild.LastBuildInfo <> 1 Then
        myTimer.Stop()
        DTE.ExecuteCommand("Build.Link")
    End If
End Sub

Ответ 12

Не знаю, если это все еще проблема и сколько улучшений вы получили в menatime, но если все равно стоит, что msbuild не знает, как организовать одновременно в рамках одного проекта (каждый cpp должен быть отдельно настраиваемым, если вы не у вас есть некоторые кодегины - кодеги лучше всего переместить в отдельный проект), вам нужно скачать комплект для разработки драйверов или .NET SSCLI, поскольку они оба имеют nmake, которые, как известно, хорошо парализуют. У SSCLI уже была построена сборка сборки, не помните, если у DDK есть некоторые образцы сборки, вы должны начать с нуля.

Также немного старая статья в статье о рассылке MSBuild не затрагивает деталей, но упоминает некоторую разницу между фактическим msbuild и msbuild + sln. Если проблема /MP vs./Gm была единственной проблемой, вам может понадобиться немного сделать script или С# exe для редактирования файлов .proj для сборки в лаборатории. Или используйте явное ограничение строки cmd в проектах и ​​выберите эту опцию из env var.