Профильная оптимизация

Оптимизация по профилю (PGO) позволяет оптимизировать весь исполняемый файл. Оптимизатор использует данные из тестовых запусков .exe или .dll файла. Данные представляют вероятную производительность программы в рабочей среде.

Примечание.

SPGO (оптимизация, управляемая профилем на основе выборки) — это альтернативный подход, использующий аппаратные счетчики производительности процессора в Windows вместо инструментирования кода. SPGO не требует инструментированной сборки — вы профилируете существующий релизный двоичный файл с помощью xperf. Дополнительные сведения см. в статьях Знакомство с оптимизацией на основе выборочного профиля в MSVC и Руководство по оптимизации на основе выборочного профиля (SPGO).

Оптимизация с помощью профилей доступна только для собственных целевых объектов x86, x64 или ARM64. Оптимизации на основе профилирования недоступны для исполняемых файлов, которые выполняются в общей исполнительной среде. Даже если создать сборку со смешанным машинным и управляемым кодом (с помощью параметра компилятора /clr), невозможно использовать профильную оптимизацию только для машинного кода. Попытка выполнить сборку проекта с этими параметрами, заданными в интегрированной среде разработки, приведет к ошибке сборки.

Примечание.

Данные, полученные в ходе тестовых запусков для профилирования, имеют приоритет над оптимизациями, которые иначе действовали бы при указании /Ob, /Os или /Ot. Дополнительные сведения см. в статьях Параметр /Ob (расширение встраиваемых функций) и /Os, /Ot (приоритет размера кода или скорости кода).

Действия по оптимизации приложения

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

  • Скомпилируйте один или несколько файлов исходного кода с параметром /GL.

    Компилятор проверяет каждый модуль, созданный с помощью /GL во время тестов оптимизации с помощью профиля, для отслеживания поведения во время выполнения. Вам не нужно компилировать каждый модуль в сборке с оптимизацией на основе профилирования с помощью /GL. Однако только модули, скомпилированные с /GL, инструментируются и впоследствии становятся доступными для оптимизации на основе профилирования.

  • Ссылка с помощью /LTCG и /GENPROFILE или /FASTGENPROFILE.

    При использовании одновременно /LTCG и /GENPROFILE или /FASTGENPROFILE инструментированное приложение при запуске создает файл .pgd. После добавления тестовых данных в .pgd файл его можно использовать в качестве входных данных на следующем шаге ссылки (создание оптимизированного образа). При указании /GENPROFILE можно дополнительно указать аргумент PGD=filename, чтобы задать нестандартные имя или расположение для файла .pgd. Сочетание параметров компоновщика /LTCG и /GENPROFILE или /FASTGENPROFILE заменяет устаревший параметр компоновщика /LTCG:PGINSTRUMENT.

  • Профилирование приложения.

    Каждый раз при завершении профилированного сеанса EXE или выгрузки профилированного DLL процесс создает appname!N.pgc файл. Файл .pgc содержит сведения об определенном тестовом запуске приложения. имя приложения — это имя приложения, а N — это число, начиная с 1. Он увеличивается на основе количества других appname!N.pgc файлов в каталоге. Можно удалить файл .pgc, если тестовый запуск не представляет сценарий, который вы хотите оптимизировать.

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

    Ваше приложение также способно напрямую вызывать функцию PGO PgoAutoSweep для записи данных профиля в момент этого вызова как файл .pgc. Она обеспечивает более точный контроль над кодом, охватываемым записанными данными в файлах .pgc. Пример использования этой функции см. в документации по PgoAutoSweep.

    При создании инструментированной сборки сбор данных по умолчанию осуществляется в непотокобезопасном режиме, который обеспечивает более высокую скорость, но, возможно, в ущерб точности. С помощью аргумента EXACT для /GENPROFILE или /FASTGENPROFILE можно настроить сбор данных в потокобезопасном режиме, который точнее, но медленнее. Этот параметр также доступен, если вы задаете нерекомендуемую переменную среды PogoSafeMode или нерекомендуемый параметр компоновщика /POGOSAFEMODE при создании инструментированной сборки.

  • Ссылка с помощью /LTCG и /USEPROFILE.

    Для создания оптимизированного образа используйте параметры компоновщика /LTCG и /USEPROFILE. Этот шаг принимает .pgd файл в качестве входных данных. При указании /USEPROFILE можно также добавить аргумент PGD=filename, чтобы указать нестандартное имя файла .pgd или его расположение. Это имя можно также указать с помощью устаревшей опции компоновщика /PGD. Сочетание параметров компоновщика /LTCG и /USEPROFILE заменяет устаревшие параметры компоновщика /LTCG:PGOPTIMIZE и /LTCG:PGUPDATE.

Даже можно создать оптимизированный исполняемый файл, а затем определить, что больше профилирования будет полезно для создания более оптимизированного образа. Если доступны инструментированный образ и его файл .pgd, можно выполнить дополнительные тестовые прогоны и перестроить оптимизированный образ с более новым файлом .pgd, используя те же параметры компоновщика /LTCG и /USEPROFILE.

Примечание.

Файлы .pgc и .pgd являются файлами двоичного типа. Если вы храните их в системе управления версиями, избегайте автоматического преобразования, которое может быть сделано в текстовые файлы.

Оптимизации, выполняемые PGO

Оптимизации с помощью профилей включают следующие проверки и улучшения:

  • Встраивание — например, если функция A часто вызывает функцию B, а функция B относительно невелика, оптимизации на основе профилирования встраивают функцию B в функцию A.

  • Спекуляция виртуальных вызовов — если виртуальный вызов или вызов через указатель функции часто направлен на определенную функцию, профильная оптимизация может вставить условно выполняемый прямой вызов этой функции, и прямой вызов может быть встроен.

  • Распределение регистров — оптимизация на основе данных профиля улучшает распределение регистров.

  • Простая блочная оптимизация — позволяет разместить часто выполняемые основные блоки, которые временно выполняются во фрейме, в одном наборе страниц (локально). Это минимизирует число используемых страниц, уменьшая тем самым затраты памяти.

  • Оптимизация размера и скорости — функции, на которые программа тратит больше всего времени, могут быть оптимизированы по скорости.

  • Макет функции — на основе графа вызовов и профилированного поведения вызывающего и вызываемого, функции, которые обычно относятся к одному пути выполнения, размещаются в одном разделе.

  • Оптимизация условного ветвления — с помощью зондов значений профильная оптимизация может определить, используется ли заданное значение в операторе switch чаще, чем другие значения. Затем это значение может быть извлечено из оператора switch. Ту же оптимизацию можно выполнить с помощью инструкций if...else, где оптимизатор может упорядочить if...else так, чтобы первым был размещён либо блок if, либо else, в зависимости от того, какой блок чаще принимает значение true.

  • Разделение неиспользуемого кода — оптимизация, управляемая профилем, перемещает код, который не вызывается во время профилирования, в специальную секцию в конце набора секций. Это позволяет вынести раздел из часто используемых страниц.

  • Отделение кода EH — так как код EH выполняется только в случае исключений, во многих случаях его можно поместить в отдельный раздел. Оптимизации, управляемые профилем, перемещают его, когда они определяют, что исключения происходят только в исключительных условиях.

  • Встроенные функции памяти — будь то расширение встроенной или не зависит от того, часто ли он вызывается. Встроенная функция также может быть оптимизирована с учетом размера блока операций перемещения или копирования.

Следующие шаги

Дополнительные сведения об этих переменных среды, функциях и средствах, которые можно использовать в оптимизации с помощью профилей, см. в следующих ресурсах:

Переменные окружения для оптимизаций с учетом профиля
Эти переменные указывают поведение сценариев тестирования во время выполнения. В настоящее время они являются устаревшими и заменены новыми параметрами компоновщика. В этом документе описывается, как перейти от переменных среды к параметрам компоновщика.

PgoAutoSweep
Функция, которую можно добавить в приложение, чтобы обеспечить детальный контроль над данными, записываемыми в файл .pgc.

pgosweep
Программа командной строки, которая записывает все данные профиля в файл .pgc, закрывает файл .pgc и открывает новый файл .pgc.

pgomgr
Программа командной строки, которая добавляет данные профиля из одного или нескольких файлов .pgc в файл .pgd.

Практическое руководство. Объединение нескольких профилей PGO в один профиль
Примеры использования pgomgr.

Пример руководства по оптимизации на основе профиля (SPGO)
Используйте счетчики производительности оборудования ЦП вместо инструментирования. Инструментированная сборка не требуется — профилируйте уже имеющийся релизный двоичный файл с помощью xperf.

См. также

Дополнительные средства сборки MSVC