Устранение неполадок при встраивание функции во время сборки
Используйте представление "Функции Build Insights" для устранения последствий применения функции при настройке времени сборки в проектах C++.
Необходимые компоненты
- Visual Studio 2022 17.8 или более поздней версии.
- Аналитика сборки C++ включена по умолчанию, если установить рабочую нагрузку C++ или разработку игр с помощью рабочей нагрузки C++.
Отображается список установленных компонентов. Аналитика сборки C++ выделена и выбрана, что означает, что она установлена.
Отображается список установленных компонентов. Аналитика сборки C++ выделена и выбрана, что означает, что она установлена.
Обзор
Build Insights, интегрированная в Visual Studio, помогает оптимизировать время сборки, особенно для крупных проектов, таких как игры AAA. Аналитика сборки предоставляет аналитические сведения, такие как представление функций , которое помогает диагностировать дорогостоящее создание кода во время сборки. Отображается время, необходимое для создания кода для каждой функции, и показывает влияние __forceinline
.
Директива __forceinline
сообщает компилятору встраивать функцию независимо от его размера или сложности. Встраивание функции может повысить производительность среды выполнения, уменьшая затраты на вызов функции. Компромисс заключается в том, что он может увеличить размер двоичного файла и повлиять на время сборки.
Для оптимизированных сборок время, затраченное на создание кода, значительно повышает общее время сборки. Как правило, оптимизация функций C++ выполняется быстро. В исключительных случаях некоторые функции могут стать достаточно большими и сложными, чтобы оказать давление на оптимизатор и заметно замедлить сборки.
В этой статье вы узнаете, как использовать представление "Функции Build Insights" для поиска узких мест в сборке.
Задание параметров сборок
Чтобы измерить результаты __forceinline
сборки выпуска, используйте сборку выпуска , так как отладочные сборки не встраиваются __forceinline
, так как отладочные сборки используют /Ob0
переключатель компилятора, который отключает эту оптимизацию. Задайте сборку для выпуска и x64:
- В раскрывающемся списке "Конфигурации решений" выберите "Выпуск".
- В раскрывающемся списке платформ решений выберите x64.
Задайте уровень оптимизации максимальной оптимизации:
В обозревателе решений щелкните правой кнопкой мыши имя проекта и выберите Свойства.
В свойствах проекта перейдите к оптимизации C/C++>.
Задайте в раскрывающемся списке "Оптимизация" значение "Максимальная оптимизация" (скорость использования) (
/O2
).Нажмите кнопку ОК , чтобы закрыть диалоговое окно.
Запуск Аналитики сборки
В выбранном проекте и использовании параметров сборки выпуска, заданных в предыдущем разделе, запустите Build Insights, выбрав в главном меню >Build Insights для перестроения выборок.> Вы также можете щелкнуть проект правой кнопкой мыши в обозревателе решений и выбрать команду "Выполнить сборку аналитики".> Выберите "Перестроить", а не "Сборка", чтобы оценить время сборки для всего проекта, а не только для нескольких файлов, которые могут быть грязные прямо сейчас.
После завершения сборки откроется файл журнала трассировки событий (ETL). Он сохраняется в папке, на которую указывает переменная среды Windows TEMP
. Созданное имя основано на времени сбора.
Представление функции
В окне для файла ETL выберите вкладку "Функции ". В нем показаны скомпилированные функции и время создания кода для каждой функции. Если объем кода, созданного для функции, не является незначительным, он не будет отображаться в списке, чтобы избежать снижения производительности сбора событий сборки.
В столбце "Имя функции" выделено значение performPhysicsCalculations() и помечается значком огня.:::
Столбец Time [sec, %] показывает, сколько времени потребовалось для компиляции каждой функции в время ответственности за стены (WCTR). Эта метрика распределяет время настенных часов между функциями на основе использования параллельных потоков компилятора. Например, если два разных потока компилируют две разные функции одновременно в течение одного секунды, wcTR каждой функции записывается как 0,5 секунды. Это отражает пропорциональную долю каждой функции общего времени компиляции, учитывая ресурсы, используемые во время параллельного выполнения. Таким образом, WCTR обеспечивает более высокую оценку влияния каждой функции на общее время сборки в средах, где одновременно происходит несколько действий компиляции.
Столбец Forceinline Size показывает примерно, сколько инструкций было создано для функции. Щелкните шеврон перед именем функции, чтобы увидеть отдельные встроенные функции, которые были развернуты в этой функции, сколько инструкций было создано для каждого.
Список можно сортировать, щелкнув столбец времени , чтобы узнать, какие функции занимают больше всего времени для компиляции. Значок "fire" указывает, что стоимость создания этой функции высока и стоит исследовать. Чрезмерное __forceinline
использование функций может значительно замедлить компиляцию.
Вы можете найти определенную функцию с помощью поля "Функции фильтра ". Если время создания кода функции слишком мало, оно не отображается в представлении функций .
Улучшение времени сборки путем настройки встраиваемых функций
В этом примере performPhysicsCalculations
функция занимает больше всего времени для компиляции.
В столбце "Имя функции" выделена и помечена значок пожара.
Изучая далее, выбрав шеврон перед этой функцией, а затем сортируя столбец Forceinline Size от самого высокого до самого низкого, мы видим крупнейших участников проблемы.
performPhysicsCalculations() расширяется и отображает длинный список функций, которые были вложены внутри него. Существует несколько экземпляров таких функций, как complexOperation(), рекурсивныйHelper() и sin() показан. Столбец Forceinline Size показывает, что complexOperation() является самой большой встроенной функцией по 315 инструкциям. рекурсивныйHelper() содержит 119 инструкций. Sin() содержит 75 инструкций, но есть много экземпляров, чем другие функции.
Существуют некоторые более крупные встроенные функции, такие как Vector2D<float>::complexOperation()
и Vector2D<float>::recursiveHelper()
которые способствуют проблеме. Но есть много дополнительных экземпляров (не все показаны здесь) Vector2d<float>::sin(float)
из , Vector2d<float>::cos(float)
и Vector2D<float>::power(float,int)
Vector2D<float>::factorial(int)
. При добавлении этих инструкций общее количество созданных инструкций быстро превышает несколько крупных созданных функций.
Глядя на эти функции в исходном коде, мы видим, что время выполнения будет потрачено внутри циклов. Например, ниже приведен код для factorial()
:
static __forceinline T factorial(int n)
{
T result = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < i; ++j) {
result *= (i - j) / (T)(j + 1);
}
}
return result;
}
Возможно, общая стоимость вызова этой функции незначительна по сравнению с стоимостью самой функции. Создание встроенной функции является наиболее полезным, когда требуется время вызова функции (отправка аргументов в стеке, переход к функции, всплывающие аргументы возврата и возврат из функции) примерно совпадает с временем выполнения функции, и когда функция вызывается много. Если это не так, может быть снижение отдачи при его встроенном использовании. Мы можем попытаться удалить директиву __forceinline
из нее, чтобы узнать, помогает ли она во время сборки. Код для power
, sin()
и cos()
аналогичен тому, что код состоит из цикла, который будет выполняться много раз. Мы можем также попытаться удалить директиву __forceinline
из этих функций.
Повторно выполните сборку Insights из главного меню, выбрав >команду Build Run Build Insights для перестроения выделения.> Вы также можете щелкнуть проект правой кнопкой мыши в обозревателе решений и выбрать команду "Выполнить сборку аналитики".> Мы выбираем перестроение вместо сборки, чтобы оценить время сборки для всего проекта, как и раньше, а не только для нескольких файлов, может быть грязно прямо сейчас.
Время сборки больше не отображается в представлении функций с 25,181 секунд до 13,376 секунд, и performPhysicsCalculations
функция больше не отображается в представлении "Функции ", так как она не способствует достаточному количеству времени сборки.
В столбце "Имя функции" выделено значение performPhysicsCalculations() и помечается значком огня.:::
Время сеанса диагностики — это общее время сборки, а также любые затраты на сбор данных Build Insights.
Следующим шагом будет профилирование приложения, чтобы узнать, негативно влияет ли производительность приложения на изменение. Если это так, мы можем выборочно добавить __forceinline
обратно по мере необходимости.
Перейдите к исходному коду
Дважды щелкните, щелкните правой кнопкой мыши или нажмите клавишу ВВОД в режиме "Функции ", чтобы открыть исходный код для этого файла.
Советы
- Вы можете >сохранить файл как ETL-файл в более постоянном расположении, чтобы сохранить запись времени сборки. Затем вы можете сравнить его с будущими сборками, чтобы узнать, улучшается ли время сборки.
- Если вы непреднамеренно закройте окно Build Insights, повторно откройте его, найдя
<dateandtime>.etl
файл во временной папке. ПеременнаяTEMP
среды Windows предоставляет путь к папке временных файлов. - Чтобы получить сведения о данных Build Insights с помощью Windows Анализатор производительности (WPA), нажмите кнопку "Открыть в WPA" в правом нижнем углу окна ETL.
- Перетащите столбцы, чтобы изменить порядок столбцов. Например, вы можете предпочесть перемещение столбца Time в первый столбец. Вы можете скрыть столбцы, щелкнув правой кнопкой мыши заголовок столбца и отменив выбор столбцов, которые вы не хотите видеть.
- Представление "Функции" предоставляет поле фильтра для поиска интересующей вас функции. Он выполняет частичные совпадения по указанному имени.
- Если вы забыли, как интерпретировать то, что представление функций пытается показать вам, наведите указатель мыши на вкладку, чтобы увидеть подсказку, описывающую представление. При наведении указателя мыши на вкладку "Функции " подсказка говорит: "Представление, показывающее статистику функций, в которых дочерние узлы являются принудительно встроенными функциями".
Устранение неполадок
- Если окно "Аналитика сборки" не отображается, выполните перестроение вместо сборки. Окно "Аналитика сборки" не отображается, если ничего на самом деле не выполняется; это может быть так, если файлы не изменились с момента последней сборки.
- Если представление "Функции" не отображает какие-либо функции, возможно, вы не создаете нужные параметры оптимизации. Убедитесь, что вы создаете выпуск с полными оптимизациями, как описано в разделе "Настройка параметров сборки". Кроме того, если время создания кода функции слишком мало, оно не отображается в списке.
См. также
Советы и рекомендации по созданию аналитических сведений
Встроенные функции (C++)
Просто об ускорении сборок C++: новая метрика времени
Создание аналитики в видео Visual Studio — Pure Virtual C++ 2023
Устранение неполадок с воздействием файла заголовка на время сборки
Представление функций для build Insights в Visual Studio 2022 17.8
Руководство. Средство vcperf и Windows Performance Analyzer
Ускорение создания кода с помощью C++ Build Insights