- PVSM.RU - https://www.pvsm.ru -
Профильная оптимизация [1] это очень интересный способ оптимизации кода приложения в среде выполнения (в команде разработчиков Visual C этот метод называют POGO или PGO, от английского Profile Guided Optimization). Впервые профильная оптимизация была применена в конце 90-х исследовательскими группами в Visual C и Microsoft. Тогда она была рассчитана для архитектуры Itanium. Затем PGO была включена в состав Visual Studio C/C++ 2005. На сегодня это основной процесс оптимизации, значительно повышающий производительность приложений Microsoft и других разработчиков.
В этом посте будет рассказано, как создавать более быстрые и высокопроизводительные нативные приложения. Для начала, познакомимся ближе с PGO, а затем рассмотрим на примере (симуляция NBody), как с помощью нескольких простых шагов можно применить этот процесс оптимизации в ваших приложениях. Для работы используйте исходный код из примера [2]. Для сборки проекта вам понадобится DirectX SDK [3].
Традиционные компиляторы работают с оптимизацией на основе статических исходных файлов. Они анализируют текст исходного файла, но не принимают в расчет данные, вводимые пользователями, о которых просто невозможно знать из кода. Рассмотрим этот псевдокод:
При работе с функцией whichBranchIsTaken компилятор не знает, как часто параметр «a» будет меньше параметра «b», и сколько раз будет применено условие «if» (т. е. компилятор не может предсказывать ветвления). При работе с функциями девиртуализации и switchCaseExpansion компилятор знает недостаточно о значениях *p и i, что делает невозможным оптимизацию девиртуализации и расширений параметров. Эти проблемы проявятся еще ярче, если мы подставим данный фрагмент кода в разные модули (например, разные объектные файлы), поскольку функции традиционной компиляции не могут быть оптимизированы для работы в пределах исходных модулей.
Базовая модель компилятора и компоновщика не так уж и плоха, но в ней недостает двух основных возможностей для оптимизации. Во-первых, в ней не используется информация, которую можно было бы получить на основе анализа всех исходных файлов (традиционные компиляторы оптимизируют только отдельные объектные файлы). Во-вторых, в ней не проводится оптимизация на базе ожидаемой или профильной реакции приложения. Первый недостаток может быть исправлен с помощью переключателя компилятора (/GL [4]) или переключателя компоновщика (/LTCG [5]), выполняющего полную оптимизацию программы и необходимого для профильной оптимизации приложения. После того, как оптимизация полной программы включена, вы можете применять профильную оптимизацию. Остановимся на ней подробнее.
PGO – это процесс оптимизации компилятора в среде выполнения, применяющий данные профиля, собранные в ходе выполнения важных или требующих высокой производительности пользовательских сценариев, с целью оптимизации приложения. Профильная оптимизация обладает рядом преимуществ по сравнению с традиционной статической оптимизацией, поскольку она принимает в расчет, как будет себя вести приложение в рабочей среде. Благодаря этому оптимизатор может осуществлять оптимизацию по скорости (для частых пользовательских сценариев) или оптимизацию по размеру (для редких сценариев). В результате код становится более лаконичным, что, в конечном счете, повышает производительность приложения.
В настоящее время PGO может применяться только на классических приложениях для настольных компьютеров и поддерживается на платформах x86 и х64. PGO представляет собой процесс, состоящий из трех этапов, как это показано на рисунке выше.
Пользователи PGO зачастую ошибочно считают, что все три фазы (инструментирование, обучение и оптимизация) должны проводиться каждый раз при построении проекта. На самом деле, первые две фазы могут быть исключены при построении последующих версий, а код при этом может претерпевать значительные изменения по сравнению с версией, полученной после фазы обучения приложения. В больших коллективах один разработчик может отвечать за проведение PGO и поддержку базы данных обучения (.pgd) в репозитории исходного кода. Другие разработчики могут синхронизировать свои репозитарии кода с этой базой и использовать файлы обучения для построения PGO-оптимизированных версий приложений. После определенного количества перекомпиляций приложение будет окончательно оптимизировано.
Теперь, когда мы знаем немного больше о профильной оптимизации, рассмотрим ее применение на конкретном примере. Профильную оптимизацию приложения можно осуществлять с помощью Visual Studio или командной строки разработчика. Ниже рассмотрен пример работы в Visual Studio с приложением под условным названием «Nbody Simulation». Если вы хотите узнать больше о PGO в командной строке, обратитесь к этим статьям [6]. Для начала работы загрузите решение в Visual Studio и выберите конфигурацию построения для работы (т.е. «Release»).
Как было упомянуто выше, PGO состоит из трех этапов: инструментирования, обучения и оптимизации. Для создания инструментированной версии приложения, нажмите правой кнопкой мыши по названию проекта («NBodyGravityCPU») и выберите раздел «Instrument» в меню «Profile Guided Optimization».
В Visual Studio будет построена инструментированная версия приложения. После этого можно переходить к фазе обучения. Запустите инструментированную версию приложения. Для этого зайдите в меню «Profile Guided Optimization» и выберите «Run Instrumented/Optimized Application». В нашем случае приложение выполняется с максимально большим телом кода (15360), т. к. будет реализован стабильный пользовательский сценарий, требующий высокой производительности. После того как два основных показателя производительности приложения — FPS (кадров в секунду) и GFlop – примут устойчивые значения, вы можете закрыть приложение. На этом фаза обучения будет завершена, а полученные данные будут сохранены в файле .pgc. По умолчанию файл .pgc будет включен в вашу конфигурацию построения, т.е. каталог «Release». Например, в результате этого обучения создается файл NBodyGravityCPU!1.pgc.
NBody Simulation представляет собой очень простое приложение, созданное исключительно для иллюстрации процесса PGO. В действительности может существовать множество вариантов сценариев обучения приложений. В частности, можно производить обучение в несколько этапов, разделенных по времени. Для записи таких сценариев обучения лучше всего использовать команду pgosweep [7] в командной строке разработчика после того, как инструментированная версия уже создана (напр., в Visual Studio).
В ходе последней фазы PGO создается оптимизированная версия приложения. В меню «Profile Guided Optimization» выберите «Optimize». Будет создана оптимизированная версия приложения. В выходном журнале PGO-построения вы увидите обобщенную информацию о проведенной операции.
Как было сказано выше, информация из файлов .pgc, полученная в ходе фазы обучения, включается в базу данных .pgd, которая затем используется матрицей оптимизации внутреннего компилятора. В большинстве случаев (за исключением небольших быстрых приложений) критерий оптимизации скорость/размер определяется соотношением динамических инструкций для определенной функции. Функции с большим числом инструкций (т. н. «горячие») оптимизируются на скорость, а с малым количеством инструкций (т. н. «холодные») – на размер.
Это практически все, что вам необходимо для того чтобы начать профильную оптимизацию в ваших приложениях. Попробуйте применить PGO для своих приложений и оцените результаты! И обязательно загляните в блог Инструменты для разработчика [8], возможно вы найдете там еще какие либо интересные решения!
Автор поста — Анкит Астхана (Ankit Asthana [9]) — руководитель программы по внутреннему компилятору Microsoft Visual С++.
Автор: dmandreev
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/optimizatsiya-koda/35100
Ссылки в тексте:
[1] Профильная оптимизация: http://msdn.microsoft.com/ru-ru/library/vstudio/e7k32f4k.aspx
[2] примера: http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-40-74-38/NBody.zip
[3] DirectX SDK: http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/DirectX%20SDK
[4] /GL: http://msdn.microsoft.com/en-us/library/0zza0de8.aspx
[5] /LTCG: http://msdn.microsoft.com/en-us/library/xbf3tbeh.aspx
[6] этим статьям: http://msdn.microsoft.com/ru-ru/library/aa289170(v=vs.71).aspx
[7] pgosweep: http://msdn.microsoft.com/ru-ru/library/9hwkw6e8.aspx
[8] Инструменты для разработчика: http://blogs.msdn.com/b/developer-tools-rus/
[9] Ankit Asthana: http://blogs.msdn.com/487959/ProfileUrlRedirect.ashx
[10] Источник: http://habrahabr.ru/post/180777/
Нажмите здесь для печати.