Pull to refresh

Comments 26

> Memory Intrinsics
это всякие memmove, memcpy,…
Вместо вызова функции они могут быть заинлайнены.
Ну и оптимизация по параметру размера копируемого/перемещаемого блока памяти.
Грубо говоря, если размер всегда кратен 4, то добивку остатка от деления на 4 можно не делать, а просто копировать 4байтовыми словами.
ах да, и график с нулём в -5 это эпично.
Там есть пару точек где было незначительное уменьшение производительности, поэтому я взял шакалу от -5%. Хотя согласен выглядит странно, надо было наверное взять от 0%. Но перестраивать графики уж мочи нет.
Не знаю как GCC, а вот clang инлайнит и простые вызовы mem*(), если сочтет это нужным.
Когда я работал над GCC, PGO не очень хорошо поддерживался и на тот момент (4.6.0), не рекомендовался к использованию для сборки серьезных приложений.
Всё равно Мозилла собранная сусеводами быстрее работает :)
сделав профайлинг PGO должен был увидеть, что вы запоняете массив одними и теми же числалами и сразу выдавать правильный результат сортировки )

а по делу:
графики не очень информативны, особенно тот где надо смотреть на занимаемую цветом площадь, хорошо бы 1 картинку из которой сразу все тренды

почему вы собираете проект без -O3 хорошо бы сравнить, только оптимизации по-умолчанию (-O0), -O3( возможно еще и 1-2), PGO и PGO+-O3, тогда можно сказать: «Вот добавили PGO и это нам дало дополнительные Х процентов к уже оптимизированному коду -O3»
Я как раз собираю проект с -O3 -march=native -mtune=native без PGO, и -O3 -march=native -mtune=native с PGO. Просто забыл указать это в статье. Все графики показывают прирост к -O3 -march=native -mtune=native.

Может быть стоит проверить ещё и с другими флагами.
торможу ) у меня MacOS subdir.mk открыл пустым, какойто левой софтиной… просмотрел его текстовым вьювером — все на месте )
PGO это просто невероятная штука. Использовал ее для сборки эмулятора генезиса Picodrive для Dingoo A320, получил двойной прирост в скорости. Есть одна особенность — когда кросс-компилируете, ну или просто компилируете с profile-generate, gcda файлы будут сохраняться в папке, где программа была скомпилирована, поэтому есть такая хорошая переменная GCOV_PREFIX.
Ага. А я не знал про GCOV_PREFIX и по старинке просто копировал gcda в место где ожидает его GCC. :)
Всё-таки есть ложка дёгтя. Если вы используете PGO, то процесс полной сборки у вас существенно замедляется, а также требует дополнительных тестовых данных (на которых вы запускаете программу, чтобы собрать статистику). Чтобы решить эту проблему возникает естественное желание на билдовой машине собирать готовую версию с PGO (и хранить там тестовые данные), а на локальных — обходиться «по старинке». Но в этом случае становится весьма трудно измерить эффект от других оптимизаций, которые тоже, конечно же, нужно делать.
Я сейчас планирую попробовать PGO на VC и GCC на реальном проекте. Изначально думал о том, чтобы данные для профиля собрать один раз, хранить в репозитории, и, скажем, обновлять раз в месяц (проект не сильно активно изменяется).
Получится ли такое? Или это как файлы с символами — должно быть абсолютное совпадение?
Возможно есть какой-то обходной путь решения этой проблемы, который мне не известен. Но даже если просто поменять оптимизационные флаги компилияции, то GCC уже начинает ругаться. Если скомпилировать программу для генерации статистики (флаг -fprofile-generate) с одними оптимизационными флагами, например -O0. И передать полученный gcda файл для компиляции с флагом -O3 и PGO оптимизацией (флаг -fprofile-use), то GCC начинает валить предупреждения вроде того что не могу найти функцию в статистике и прочее.
проект не сильно активно изменяется

С вашей точки зрения проект не сильно меняется, потому что вы правите мало строк. Но ваши правки строк могут очень сильно влиять на код. Например, вы правите «один жалкий макрос», а этот макрос разворачивается в десятках тысяч мест в коде. Или вы правите одну строку в шаблоне, а шаблон — не конечный код, это только заготовка, которая используется десятки и сотни раз с разными параметрами и каждый раз получается новый класс или новая функция — правка на них повлияет. Так что одна правка может очень сильно повлиять на выходной файл. Учтите, что PGO управляет генерацией машинного кода — т.е. самой последней стадией. Если что-то там отъедет, вы будете это отлаживать до конца дней. На мой взгляд, это очень рискованная затея.
Это-то я понимаю. Правку общей библиотеки, которая используется десятком проектов, не назовешь мелкой правкой.
Точно так же в пределах одного проекта можно исправить «чуть-чуть» — и код заметно поменяется.
Ну, автор статьи уже выше ответил, что даже если изменится один проект из восьмидесяти, то на этот проект будет достаточная пачка warning'ов, чтобы отпугнуть делать такие эксперименты.

Хотя я еще попробую как-то оптимизировать этот процесс, когда буду прикручивать PGO к проекту :)
Для выпуска релизных версий это вполне нормально. Их не каждый день собирают.
Я думаю имело смысл протестировать с менее регулярными данными для сортировки (во имя рандома!).
Ещё неплохо было бы указать использованное железо. Ну и из разряда высшего пилотажа — посмотреть результаты на процессоре с другим объёмом кэша.
Интересно вот что. Предположим, я собираю программу с PGO и в моем профилировочном пакете данные немного не такие (насколько не такие — не знаю), как будут у реальных пользователей. Станет ли моя программа работать у реальных пользователей медленнее, чем если бы она была собрана без PGO? Если да, то какого ухудшения мне ждать?
Не думаю, что такого эффекта можно добиться случайно.
Тут можно только гадать. Полезность любой оптимизации можно оценить через тесты. По моему мнению, PGO лишь предоставляет данные компилятору для более осознанного выбора оптимизаций. Без PGO при оптимизации компилятор будет исходить из других предпосылок. Возможно он оптимизирует программу, абсолютно так же, а может и нет. Результат может быть разный.

Ну в источниках которые я читал пред написание статьи сказано весьма гладко, мол при не типичном сценарии возможность уменьшения производительности есть, не каких реальных фактов не встречал. Так что только тестирование…
Туманно получается. Я же не могу предугадать все возможные реальные пакеты.
Ну почему туманно-то? Вполне соответствует ожиданиям:
1. Если есть понимание, что за прграмму мы пишем и на каких сценариях оно работает, даём типичный сценарий и PGO поможет;
2. Если это понимание есть, но хочется найти пример, когда PGO вредит, будучи обученным на неудачных данных — скорее всего и эту задачу можно решить;
3. Если такого понимания нет, то прежде всего стоит разобраться с собственной программой, чем с настройками PGO.
Sign up to leave a comment.

Articles