Оптимизация на основе профиля (также известная как PGO или «pogo» ) — это способ дальнейшей оптимизации оптимизированных сборок вашей игры с использованием информации о том, как ваша игра ведет себя в реальном мире. Таким образом, нечасто запускаемый код, такой как ошибки или крайние случаи, вытесняется из критических путей выполнения вашего кода, что ускоряет его.
Рисунок 1. Обзор того, как работает PGO.
Чтобы использовать PGO, вы сначала инструментируете свою сборку для генерации данных профиля, с которыми может работать компилятор. Затем вы тестируете свой код, запуская эту сборку и создавая один или несколько файлов данных профиля. Наконец, вы копируете эти файлы обратно с устройства и используете их с компилятором для оптимизации вашего исполняемого файла с использованием собранной вами информации профиля.
Как работают оптимизированные сборки без PGO
Сборка, оптимизированная без использования данных профиля, использует ряд эвристик при принятии решения о том, как генерировать оптимизированный код.
Некоторые из них сообщаются разработчиком явно — например, в C++ 20 или более поздних версиях с помощью подсказок направления ветвления, таких как [[likely]]
и [[unlikely]]
. Другим примером может быть использование ключевого слова inline
или даже __forceinline
(хотя в целом лучше и гибче придерживаться первого). По умолчанию некоторые компиляторы предполагают, что первая часть ветки (то есть оператор if
, а не часть else
) является наиболее вероятной. Оптимизатор также может делать предположения на основе статического анализа кода о том, как он будет выполняться, но обычно это ограничено.
Проблема с этими эвристиками заключается в том, что они не могут правильно помочь компилятору во всех ситуациях – даже при исчерпывающей ручной разметке – поэтому, хотя генерируемый код обычно хорошо оптимизирован, он не так хорош, как мог бы быть, если бы компилятор имел дополнительную информацию о его поведении во время выполнения.
Создание профиля
Когда ваш исполняемый файл создается с включенным PGO в инструментированном режиме, ваш исполняемый файл дополняется кодом в начале каждого блока кода — например, в начале функции или в начале каждой ветви ветки. Этот код используется для отслеживания количества случаев входа в блок при выполнении кода, который компилятор может использовать позже для создания оптимизированного кода.
Также выполняется некоторое другое отслеживание — например, размер типичных операций копирования в блоке, чтобы позже можно было генерировать быстрые встроенные версии операции.
После того, как игра выполнила какую-то репрезентативную работу, исполняемый файл должен вызвать функцию — __llvm_profile_write_file()
— для записи данных профиля в настраиваемое место на устройстве. Эта функция автоматически подключается к вашей игре, если в вашей конфигурации сборки включен инструментарий PGO.
Записанный файл данных профиля затем следует скопировать обратно на главный компьютер и предпочтительно хранить в месте вместе с другими профилями той же сборки, чтобы их можно было использовать вместе.
Например, вы можете изменить код игры, чтобы он вызывал __llvm_profile_write_file()
когда текущая игровая сцена заканчивается. Затем, чтобы получить профиль, вы должны создать свою игру с включенными инструментами, а затем развернуть ее на своем устройстве Android. Во время работы данные профиля автоматически сохраняются — ваш инженер по контролю качества просматривает игру, отрабатывая различные сценарии (или просто выполняет свой обычный тест).
Когда вы закончите тренировать различные части игры, вы можете вернуться в главное меню, что завершит текущую игровую сцену и запишет данные профиля.
Затем можно использовать сценарий для копирования данных профиля с тестового устройства и загрузки их в центральный репозиторий, где их можно будет сохранить для последующего использования.
Объединение данных профиля
После получения профиля от устройства его необходимо преобразовать из файла данных профиля, созданного инструментальной сборкой, в форму, которую может использовать компилятор. AGDE делает это автоматически для любых файлов данных профиля, которые вы добавляете в свой проект.
PGO предназначен для объединения результатов нескольких прогонов инструментированных профилей — AGDE также делает это автоматически, если у вас есть несколько файлов в одном проекте.
В качестве примера того, как объединение наборов данных профиля может быть полезным, предположим, что у вас есть лаборатория, полная инженеров по контролю качества, каждый из которых играет на разных уровнях вашей игры. Каждое из их прохождений записывается, а затем используется для создания данных профиля из сборки вашей игры, оснащенной PGO. Объединение профилей позволяет объединить результаты всех этих различных тестовых запусков, которые могут выполнять совершенно разные части вашего кода, чтобы получить лучшие результаты.
Более того, при выполнении продольных тестов, когда вы сохраняете копии данных профиля от внутренней версии к внутренней версии, восстановление не обязательно делает старые данные профиля недействительными. По большей части код относительно стабилен от выпуска к выпуску, поэтому данные профиля из старых сборок по-прежнему могут быть полезны и не устаревают сразу.
Создание оптимизированных сборок с учетом профиля
Добавив данные профиля в свой проект, вы можете использовать их для создания исполняемого файла, включив PGO в режиме оптимизации в конфигурации сборки.
Это предписывает оптимизатору компилятора использовать данные профиля, собранные вами ранее, при принятии решений по оптимизации.
Когда использовать оптимизацию на основе профиля
PGO не предназначен для включения в начале разработки или во время ежедневной итерации кода. Во время разработки вам следует сосредоточиться на оптимизации алгоритмов и структуры данных, поскольку они дадут вам гораздо больше преимуществ.
PGO появляется на более позднем этапе процесса разработки, когда вы готовитесь к выпуску. Думайте об оптимизации на основе профиля как о вишенке на торте, которая позволяет вам выжать последнюю каплю производительности из вашего кода после того, как вы уже потратили некоторое время на оптимизацию своего кода самостоятельно.
Ожидаемое улучшение производительности с PGO
Это зависит от большого количества факторов, в том числе от того, насколько полными и устаревшими являются ваши профили, а также от того, насколько близок к оптимальному был бы ваш код при традиционной оптимизированной сборке.
В целом, по очень консервативной оценке, затраты ЦП в ключевых потоках сократятся примерно на 5%. Вы можете увидеть разные результаты.
Накладные расходы на приборостроение
Инструментарий PGO является всеобъемлющим, и хотя он генерируется автоматически, он не бесплатен. Накладные расходы на инструментирование PGO могут варьироваться в зависимости от вашей кодовой базы.
Затраты на производительность профильно-ориентированного инструмента
Вы можете увидеть падение частоты кадров при использовании инструментированных сборок. В некоторых случаях — в зависимости от того, насколько близко к 100 % загружен ваш процессор во время нормальной работы — это падение может быть настолько большим, что затруднит нормальный игровой процесс.
Мы рекомендуем большинству разработчиков создать для своей игры полудетерминированный режим воспроизведения. Функциональность такого рода дает вашей команде контроля качества возможность запустить игру в известной, повторяемой начальной точке вашей игры (например, в сохраненной игре или на определенном тестовом уровне), а затем записать свои вводимые данные. Эти входные данные, записанные из тестовой сборки, можно передать в сборку с поддержкой PGO, воспроизвести и сгенерировать данные реального профиля независимо от того, сколько времени потребуется для обработки отдельного кадра – даже если игра работала настолько медленно, что неиграбельно.
Этот вид функциональности также имеет другие важные преимущества, такие как увеличение усилий тестировщика: один тестер может записать свои вводимые данные на устройство, а затем их можно воспроизвести на нескольких различных типах устройств в целях дымового тестирования.
Подобная система воспроизведения может иметь огромные преимущества на Android, где в экосистеме имеется большое количество вариантов устройств. И на этом преимущества не заканчиваются: она также может стать основной частью вашей системы непрерывной интеграции, позволяя вам регулярно проводите ночные регрессии производительности и дымовые тесты.
Запись должна записывать ввод пользователя в наиболее подходящей точке механизма ввода вашей игры (вероятно, не непосредственно события сенсорного экрана, а вместо этого записывая их последствия в виде команд). Эти входные данные также должны иметь счетчик кадров, который монотонно увеличивается во время игры, чтобы во время воспроизведения механизм повтора мог ожидать соответствующего кадра, в котором он должен вызвать событие.
В режиме воспроизведения ваша игра должна избегать входа в систему через Интернет, не должна показывать рекламу и должна работать с фиксированным временным интервалом (с целевой частотой кадров). Вам следует рассмотреть возможность отключения vsync.
Не важно, чтобы все (например, системы частиц) в вашей игре было идеально детерминированно повторяемым, но одни и те же действия должны приводить к одинаковым внутриигровым последствиям и результатам — то есть игровой процесс должен быть одинаковым.
Стоимость памяти для инструментов с профильным управлением
Затраты памяти на инструментарий PGO сильно различаются в зависимости от конкретной компилируемой библиотеки. В наших тестах мы наблюдали общее увеличение размера исполняемого файла теста примерно в 2,2 раза. Это увеличение размера включало как дополнительный код, необходимый для инструментирования блоков кода, так и пространство, необходимое для хранения счетчиков. Эти тесты не были исчерпывающими, и ваш опыт может отличаться.
Когда обновлять или удалять данные вашего профиля
Вам следует обновлять свои профили каждый раз, когда вы вносите большие изменения в свой код (или игровой контент).
Что это означает, в точности зависит от вашей среды сборки и того, на каком этапе разработки вы находитесь.
Как упоминалось ранее, вам не следует переносить данные профиля при серьезных изменениях в среде сборки; хотя это не помешает вам построить или сломать сборку, это снизит преимущества в производительности от использования PGO, поскольку к новой среде сборки будет применимо очень мало данных профиля. Однако это не единственный случай, когда данные вашего профиля могут устареть.
Давайте начнем с предположения, что вы не будете использовать PGO до приближения конца разработки, когда вы готовитесь к выпуску, за исключением, возможно, еженедельного сбора данных, чтобы инженеры, ориентированные на производительность, могли убедиться в отсутствии каких-либо неожиданных сбоев. ближе к релизу.
Ситуация меняется по мере приближения к окну выпуска, когда ваша команда контроля качества тестирует каждый день и тщательно прорабатывает игру. На этом этапе вы можете ежедневно создавать профили на основе этих данных и использовать их для информирования будущих сборок для тестирования производительности и корректировки собственных бюджетов производительности.
Когда вы готовитесь к выпуску, вам следует заблокировать версию сборки, которую вы планируете выпустить, а затем провести проверку качества, чтобы создать новые данные профиля. Затем вы используете эти данные для создания окончательной версии вашего исполняемого файла.
Затем отдел контроля качества может провести окончательную проверку этой оптимизированной готовой сборки, чтобы убедиться в ее пригодности к выпуску.
,Оптимизация на основе профиля (также известная как PGO или «pogo» ) — это способ дальнейшей оптимизации оптимизированных сборок вашей игры с использованием информации о том, как ваша игра ведет себя в реальном мире. Таким образом, нечасто запускаемый код, такой как ошибки или крайние случаи, вытесняется из критических путей выполнения вашего кода, что ускоряет его.
Рисунок 1. Обзор того, как работает PGO.
Чтобы использовать PGO, вы сначала инструментируете свою сборку для генерации данных профиля, с которыми может работать компилятор. Затем вы тренируете свой код, запуская эту сборку и создавая один или несколько файлов данных профиля. Наконец, вы копируете эти файлы обратно с устройства и используете их с компилятором для оптимизации вашего исполняемого файла с использованием собранной вами информации профиля.
Как работают оптимизированные сборки без PGO
Сборка, оптимизированная без использования данных профиля, использует ряд эвристик при принятии решения о том, как генерировать оптимизированный код.
Некоторые из них сообщаются разработчиком явно — например, в C++ 20 или более поздних версиях с помощью подсказок направления ветвления, таких как [[likely]]
и [[unlikely]]
. Другим примером может быть использование ключевого слова inline
или даже __forceinline
(хотя в целом лучше и гибче придерживаться первого). По умолчанию некоторые компиляторы предполагают, что первая часть ветки (то есть оператор if
, а не часть else
) является наиболее вероятной. Оптимизатор также может делать предположения на основе статического анализа кода о том, как он будет выполняться, но обычно это ограничено.
Проблема с этими эвристиками заключается в том, что они не могут правильно помочь компилятору во всех ситуациях – даже при исчерпывающей ручной разметке – поэтому, хотя генерируемый код обычно хорошо оптимизирован, он не так хорош, как мог бы быть, если бы компилятор имел дополнительную информацию о его поведении во время выполнения.
Создание профиля
Когда ваш исполняемый файл создается с включенным PGO в инструментированном режиме, ваш исполняемый файл дополняется кодом в начале каждого блока кода — например, в начале функции или в начале каждой ветви ветки. Этот код используется для отслеживания количества случаев входа в блок при выполнении кода, который компилятор может использовать позже для создания оптимизированного кода.
Также выполняется некоторое другое отслеживание — например, размер типичных операций копирования в блоке, чтобы позже можно было генерировать быстрые встроенные версии операции.
После того, как игра выполнила какую-то репрезентативную работу, исполняемый файл должен вызвать функцию — __llvm_profile_write_file()
— для записи данных профиля в настраиваемое место на устройстве. Эта функция автоматически подключается к вашей игре, если в вашей конфигурации сборки включен инструментарий PGO.
Записанный файл данных профиля затем следует скопировать обратно на главный компьютер и предпочтительно хранить в месте вместе с другими профилями той же сборки, чтобы их можно было использовать вместе.
Например, вы можете изменить код игры, чтобы он вызывал __llvm_profile_write_file()
когда текущая игровая сцена заканчивается. Затем, чтобы получить профиль, вам необходимо создать игру с включенными инструментами, а затем развернуть ее на своем устройстве Android. Во время работы данные профиля автоматически сохраняются — ваш инженер по контролю качества просматривает игру, отрабатывая различные сценарии (или просто выполняет свой обычный тест).
Когда вы закончите тренировать различные части игры, вы можете вернуться в главное меню, что завершит текущую игровую сцену и запишет данные профиля.
Затем можно использовать сценарий для копирования данных профиля с тестового устройства и загрузки их в центральный репозиторий, где их можно будет сохранить для последующего использования.
Объединение данных профиля
После получения профиля от устройства его необходимо преобразовать из файла данных профиля, созданного инструментальной сборкой, в форму, которую может использовать компилятор. AGDE делает это автоматически для любых файлов данных профиля, которые вы добавляете в свой проект.
PGO предназначен для объединения результатов нескольких прогонов инструментированных профилей — AGDE также делает это автоматически, если у вас есть несколько файлов в одном проекте.
В качестве примера того, насколько полезным может быть объединение наборов данных профиля, предположим, что у вас есть лаборатория, полная инженеров по контролю качества, каждый из которых играет на разных уровнях вашей игры. Каждое из их прохождений записывается, а затем используется для создания данных профиля из сборки вашей игры, оснащенной PGO. Объединение профилей позволяет объединить результаты всех этих различных тестовых запусков, которые могут выполнять совершенно разные части вашего кода, для получения лучших результатов.
Более того, при выполнении продольных тестов, когда вы сохраняете копии данных профиля от внутренней версии к внутренней версии, восстановление не обязательно делает недействительными старые данные профиля. По большей части код относительно стабилен от выпуска к выпуску, поэтому данные профиля из старых сборок по-прежнему могут быть полезны и не устаревают сразу.
Создание оптимизированных сборок с учетом профиля
Добавив данные профиля в свой проект, вы можете использовать их для создания исполняемого файла, включив PGO в режиме оптимизации в конфигурации сборки.
Это предписывает оптимизатору компилятора использовать данные профиля, собранные вами ранее, при принятии решений по оптимизации.
Когда использовать оптимизацию на основе профиля
PGO не предназначен для включения в начале разработки или во время ежедневной итерации кода. Во время разработки вам следует сосредоточиться на оптимизации алгоритмов и структуры данных, поскольку они дадут вам гораздо больше преимуществ.
PGO появляется на более позднем этапе процесса разработки, когда вы готовитесь к выпуску. Думайте об оптимизации на основе профиля как о вишенке на торте, которая позволяет вам выжать последнюю каплю производительности из вашего кода после того, как вы уже потратили некоторое время на оптимизацию своего кода самостоятельно.
Ожидаемое улучшение производительности с PGO
Это зависит от большого количества факторов, в том числе от того, насколько полны и устаревши ваши профили и насколько близок к оптимальному был бы ваш код при традиционной оптимизированной сборке.
В целом, по очень консервативной оценке, затраты ЦП в ключевых потоках сократятся примерно на 5%. Вы можете увидеть разные результаты.
Накладные расходы на приборостроение
Инструментарий PGO является всеобъемлющим, и хотя он генерируется автоматически, он не бесплатен. Накладные расходы на инструментирование PGO могут варьироваться в зависимости от вашей кодовой базы.
Затраты на производительность профильно-ориентированного инструмента
Вы можете увидеть падение частоты кадров при использовании инструментированных сборок. В некоторых случаях — в зависимости от того, насколько близко к 100 % загружен ваш процессор во время нормальной работы — это падение может быть настолько большим, что затруднит нормальный игровой процесс.
Мы рекомендуем большинству разработчиков создать для своей игры полудетерминированный режим воспроизведения. Функциональность такого рода дает вашей команде контроля качества возможность запустить игру в известной, повторяемой начальной точке вашей игры (например, в сохраненной игре или на определенном тестовом уровне), а затем записать свои вводимые данные. Эти входные данные, записанные из тестовой сборки, можно передать в сборку с поддержкой PGO, воспроизвести и сгенерировать данные реального профиля независимо от того, сколько времени потребуется для обработки отдельного кадра – даже если игра работала настолько медленно, что неиграбельно.
Этот вид функциональности также имеет другие важные преимущества, такие как увеличение усилий тестировщика: один тестер может записать свои вводимые данные на устройство, а затем их можно воспроизвести на нескольких различных типах устройств в целях дымового тестирования.
Подобная система воспроизведения может иметь огромные преимущества на Android, где в экосистеме имеется большое количество вариантов устройств. И на этом преимущества не заканчиваются: она также может стать основной частью вашей системы непрерывной интеграции, позволяя вам регулярно проводите ночные регрессии производительности и дымовые тесты.
Запись должна записывать ввод пользователя в наиболее подходящей точке механизма ввода вашей игры (вероятно, не непосредственно события сенсорного экрана, а вместо этого записывая их последствия в виде команд). Эти входные данные также должны иметь счетчик кадров, который монотонно увеличивается во время игры, чтобы во время воспроизведения механизм повтора мог ожидать соответствующего кадра, в котором он должен вызвать событие.
В режиме воспроизведения ваша игра должна избегать входа в систему через Интернет, не должна показывать рекламу и должна работать с фиксированным временным интервалом (с целевой частотой кадров). Вам следует рассмотреть возможность отключения vsync.
Не важно, чтобы все (например, системы частиц) в вашей игре было идеально детерминированно повторяемым, но одни и те же действия должны приводить к одинаковым внутриигровым последствиям и результатам — то есть игровой процесс должен быть одинаковым.
Стоимость памяти для инструментов с профильным управлением
Затраты памяти на инструментарий PGO сильно различаются в зависимости от конкретной компилируемой библиотеки. В наших тестах мы наблюдали общее увеличение размера исполняемого файла теста примерно в 2,2 раза. Это увеличение размера включало как дополнительный код, необходимый для инструментирования блоков кода, так и пространство, необходимое для хранения счетчиков. Эти тесты не были исчерпывающими, и ваш опыт может отличаться.
Когда обновлять или удалять данные вашего профиля
Вам следует обновлять свои профили каждый раз, когда вы вносите большие изменения в свой код (или игровой контент).
Что это означает, в точности зависит от вашей среды сборки и того, на каком этапе разработки вы находитесь.
Как упоминалось ранее, вам не следует переносить данные профиля при серьезных изменениях в среде сборки; хотя это не помешает вам построить или сломать сборку, это снизит преимущества в производительности от использования PGO, поскольку к новой среде сборки будет применимо очень мало данных профиля. Однако это не единственный случай, когда данные вашего профиля могут устареть.
Давайте начнем с предположения, что вы не будете использовать PGO до приближения конца разработки, когда вы готовитесь к выпуску, за исключением, возможно, еженедельного сбора данных, чтобы инженеры, ориентированные на производительность, могли убедиться в отсутствии каких-либо неожиданных сбоев. ближе к релизу.
Ситуация меняется по мере приближения к окну выпуска, когда ваша команда контроля качества проводит тестирование каждый день и тщательно прорабатывает игру. На этом этапе вы можете ежедневно создавать профили на основе этих данных и использовать их для информирования будущих сборок для тестирования производительности и корректировки собственных бюджетов производительности.
Когда вы готовитесь к выпуску, вам следует заблокировать версию сборки, которую вы планируете выпустить, а затем провести проверку качества, чтобы создать новые данные профиля. Затем вы используете эти данные для создания окончательной версии вашего исполняемого файла.
Затем отдел контроля качества может провести окончательную проверку этой оптимизированной готовой сборки, чтобы убедиться в ее пригодности к выпуску.
,Оптимизация на основе профиля (также известная как PGO или «pogo» ) — это способ дальнейшей оптимизации оптимизированных сборок вашей игры с использованием информации о том, как ваша игра ведет себя в реальном мире. Таким образом, нечасто запускаемый код, такой как ошибки или крайние случаи, вытесняется из критических путей выполнения вашего кода, что ускоряет его.
Рисунок 1. Обзор того, как работает PGO.
Чтобы использовать PGO, вы сначала инструментируете свою сборку для генерации данных профиля, с которыми может работать компилятор. Затем вы тренируете свой код, запуская эту сборку и создавая один или несколько файлов данных профиля. Наконец, вы копируете эти файлы обратно с устройства и используете их с компилятором для оптимизации вашего исполняемого файла с использованием собранной вами информации профиля.
Как работают оптимизированные сборки без PGO
Сборка, оптимизированная без использования данных профиля, использует ряд эвристик при принятии решения о том, как генерировать оптимизированный код.
Некоторые из них сообщаются разработчиком явно — например, в C++ 20 или более поздних версиях с помощью подсказок направления ветвления, таких как [[likely]]
и [[unlikely]]
. Другим примером может быть использование ключевого слова inline
или даже __forceinline
(хотя в целом лучше и гибче придерживаться первого). По умолчанию некоторые компиляторы предполагают, что первая часть ветки (то есть оператор if
, а не часть else
) является наиболее вероятной. Оптимизатор также может делать предположения на основе статического анализа кода о том, как он будет выполняться, но обычно это ограничено.
Проблема с этими эвристиками заключается в том, что они не могут правильно помочь компилятору во всех ситуациях – даже при исчерпывающей ручной разметке – поэтому, хотя генерируемый код обычно хорошо оптимизирован, он не так хорош, как мог бы быть, если бы компилятор имел дополнительную информацию о его поведении во время выполнения.
Создание профиля
Когда ваш исполняемый файл создается с включенным PGO в инструментированном режиме, ваш исполняемый файл дополняется кодом в начале каждого блока кода — например, в начале функции или в начале каждой ветви ветки. Этот код используется для отслеживания количества случаев входа в блок при выполнении кода, который компилятор может использовать позже для создания оптимизированного кода.
Также выполняется некоторое другое отслеживание — например, размер типичных операций копирования в блоке, чтобы позже можно было генерировать быстрые встроенные версии операции.
После того, как игра выполнила какую-то репрезентативную работу, исполняемый файл должен вызвать функцию — __llvm_profile_write_file()
— для записи данных профиля в настраиваемое место на устройстве. Эта функция автоматически подключается к вашей игре, если в вашей конфигурации сборки включен инструментарий PGO.
Записанный файл данных профиля затем следует скопировать обратно на главный компьютер и предпочтительно хранить в месте вместе с другими профилями той же сборки, чтобы их можно было использовать вместе.
Например, вы можете изменить код игры, чтобы он вызывал __llvm_profile_write_file()
когда текущая игровая сцена заканчивается. Затем, чтобы получить профиль, вы должны создать свою игру с включенными инструментами, а затем развернуть ее на своем устройстве Android. Во время работы данные профиля автоматически сохраняются — ваш инженер по контролю качества просматривает игру, отрабатывая различные сценарии (или просто выполняет свой обычный тест).
Когда вы закончите тренировать различные части игры, вы можете вернуться в главное меню, что завершит текущую игровую сцену и запишет данные профиля.
Затем можно использовать сценарий для копирования данных профиля с тестового устройства и загрузки их в центральный репозиторий, где их можно будет сохранить для последующего использования.
Объединение данных профиля
После получения профиля от устройства его необходимо преобразовать из файла данных профиля, созданного инструментальной сборкой, в форму, которую может использовать компилятор. AGDE делает это автоматически для любых файлов данных профиля, которые вы добавляете в свой проект.
PGO предназначен для объединения результатов нескольких прогонов инструментированных профилей — AGDE также делает это автоматически, если у вас есть несколько файлов в одном проекте.
В качестве примера того, как объединение наборов данных профиля может быть полезным, предположим, что у вас есть лаборатория, полная инженеров по контролю качества, каждый из которых играет на разных уровнях вашей игры. Каждое из их прохождений записывается, а затем используется для создания данных профиля из сборки вашей игры, оснащенной PGO. Объединение профилей позволяет объединить результаты всех этих различных тестовых запусков, которые могут выполнять совершенно разные части вашего кода, для получения лучших результатов.
Более того, при выполнении продольных тестов, когда вы сохраняете копии данных профиля от внутренней версии к внутренней версии, восстановление не обязательно делает старые данные профиля недействительными. По большей части код относительно стабилен от выпуска к выпуску, поэтому данные профиля из старых сборок по-прежнему могут быть полезны и не устаревают сразу.
Создание оптимизированных сборок с учетом профиля
Добавив данные профиля в свой проект, вы можете использовать их для создания исполняемого файла, включив PGO в режиме оптимизации в конфигурации сборки.
Это предписывает оптимизатору компилятора использовать данные профиля, собранные вами ранее, при принятии решений по оптимизации.
Когда использовать оптимизацию на основе профиля
PGO не предназначен для включения в начале разработки или во время ежедневной итерации кода. Во время разработки вам следует сосредоточиться на оптимизации алгоритмов и структуры данных, поскольку они дадут вам гораздо больше преимуществ.
PGO появляется на более позднем этапе процесса разработки, когда вы готовитесь к выпуску. Думайте об оптимизации на основе профиля как о вишенке на торте, которая позволяет вам выжать последнюю каплю производительности из вашего кода после того, как вы уже потратили некоторое время на оптимизацию своего кода самостоятельно.
Ожидаемое улучшение производительности с PGO
Это зависит от большого количества факторов, в том числе от того, насколько полны и устаревши ваши профили и насколько близок к оптимальному был бы ваш код при традиционной оптимизированной сборке.
В целом, по очень консервативной оценке, затраты ЦП в ключевых потоках сократятся примерно на 5%. Вы можете увидеть разные результаты.
Накладные расходы на приборостроение
Инструментарий PGO является всеобъемлющим, и хотя он генерируется автоматически, он не бесплатен. Накладные расходы на инструментирование PGO могут варьироваться в зависимости от вашей кодовой базы.
Затраты на производительность профильно-ориентированного инструмента
Вы можете увидеть падение частоты кадров при использовании инструментированных сборок. В некоторых случаях — в зависимости от того, насколько близко к 100 % загружен ваш процессор во время нормальной работы — это падение может быть настолько большим, что затруднит нормальный игровой процесс.
Мы рекомендуем большинству разработчиков создать для своей игры полудетерминированный режим воспроизведения. Функциональность такого рода дает вашей команде контроля качества возможность запустить игру в известной, повторяемой начальной точке вашей игры (например, в сохраненной игре или на определенном тестовом уровне), а затем записать свои вводимые данные. Эти входные данные, записанные из тестовой сборки, можно передать в сборку с поддержкой PGO, воспроизвести и сгенерировать данные реального профиля независимо от того, сколько времени потребуется для обработки отдельного кадра – даже если игра работала настолько медленно, что неиграбельно.
Этот вид функциональности также имеет другие важные преимущества, такие как увеличение усилий тестировщика: один тестер может записать свои вводимые данные на устройство, а затем их можно воспроизвести на нескольких различных типах устройств в целях дымового тестирования.
Такая система воспроизведения может иметь огромные преимущества на Android, где в экосистеме есть большое количество вариантов устройств - и преимущества там не заканчиваются: она может сформировать основную часть вашей системы непрерывной интеграции, позволяя вам также Выполняйте регулярные регрессии на ночь и тесты на дым.
Запись должна записывать пользовательский ввод в наиболее подходящей точке в рамках механизма ввода вашей игры (вероятно, не прямых событий с сенсорным экраном, но вместо этого записывать их последствия в качестве команд). Эти входы также должны иметь количество кадров, которое монотонно отмечает во время игрового процесса, так что во время воспроизведения механизм воспроизведения может ждать соответствующего кадра, на которой он должен вызвать событие.
В режиме воспроизведения ваша игра должна избегать онлайн-входа, не должна показывать рекламу и должна работать с фиксированным временем (на вашем целевом кадре). Вы должны рассмотреть возможность отключения VSYNC.
Не важно, чтобы все (например, системы частиц) в вашей игре совершенно детерминированно повторяется, но одни и те же действия должны обеспечить те же игровые последствия и результаты, то есть геймплей должен быть таким же.
Стоимость памяти инструментации под управлением профиля
Накладные расходы памяти PGO -инструментов сильно варьируются в зависимости от специфической библиотеки, скомпилируемой. В наших тестах мы увидели общее увеличение размера тестируемого исполняемого файла в ~ 2,2х. Такое увеличение размера включало как дополнительный код, необходимый для прибора блоков кода, так и пространство, необходимое для хранения счетчиков. Эти тесты не были исчерпывающими, и ваш опыт может отличаться.
Когда обновлять или отбросить данные профиля
Вы должны обновлять свои профили всякий раз, когда вы вносите значительные изменения в свой код (или игровой контент).
То, что это означает, именно зависит от вашей среды сборки и от того, где вы находитесь в разработке.
Как упоминалось ранее, вы не должны нести данные профиля в основных изменениях среды сборки; Несмотря на то, что это не помешает вам построить или сломать свою сборку, это снизит преимущества производительности использования PGO, поскольку очень мало данных профиля будут применимы к новой среде сборки. Однако это не единственный случай, когда данные вашего профиля могут стать устаревшими.
Давайте начнем с того, что вы не будете использовать PGO до приближения к концу развития, когда вы готовитесь к выпуску, помимо возможно, собирать еженедельный захват, чтобы инженеры, ориентированные на производительность ближе к выпуску.
Это меняется по мере приближения к окну релиза, когда ваша команда QA тестирует каждый день и проходит через игру. На этом этапе вы можете генерировать профили из этих данных ежедневно и использовать их для информирования о будущих сборках для тестирования производительности и корректировки собственных бюджетов эффективности.
Когда вы готовитесь к выпуску, вы должны заблокировать версию сборки, которую вы планируете выпустить, а затем пропустить QA, генерируя его новые данные профиля. Затем вы создаете, используя эти данные для получения окончательной версии вашего исполняемого файла.
Затем QA может дать эту оптимизированную, доставку построить окончательный проход, чтобы гарантировать, что его можно выпустить.