Информация об изменениях

Сообщение Re[10]: Иллюстрация от 07.11.2020 8:47

Изменено 07.11.2020 8:54 netch80

Re[10]: Иллюстрация
Здравствуйте, night beast, Вы писали:

N>>Это очень просто. Выкиньте из головы прибитые там гвоздями представления про универсальный подход по опциям сборки на весь код. Дальше пойдёт легче.


NB>а зачем?

NB>если существующий подход нормально работает и используемые средства разработки под него заточены.

В том и дело, что не работает он "нормально". Или, если для вас "нормально" это случай этого героя интернета, то да, нормально — но очень быстро выходишь за пределы таких ограничений.

NB>что именно мы получаем от придуманных нами каких-то дополнительных уровней отладки/сборки?


У вас некая очень толстая программа со своей историей, которую ведёт достаточно разнообразная команда. Вам надо её улучшить — например, есть конкретное место, где вам надо ускорить (неважно что — отрисовку на экране, расчёт зарплаты, парсинг сетевого запроса, etc.)
Вы определили те модули, где происходит критичное по скорости выполнение.
Вам надо в этих модулях:
1. Вылизать код относительно всех плюх.
2. Установить для него максимум оптимизации. При этом, так как оптимизации начинают вызывать предположения компилятора, которые не соответствуют предположениям программиста (вспоминаем весь комплект ужастиков про undefined behavior с переполнениями, алиасингом и т.п.) — это будет смесь визуальной верификации и запусков санитайзеров, пока не будет достигнуто выполнение, которое адекватно по скорости и не вызывает жалобы на проблемы кода.
3. Установить на всех границах этого кода контроль значений (который в идеале никогда не должен выключаться).
После этого быть всё равно готовым к тому, что что-то пойдёт не так и надо иметь базовую информацию хотя бы на уровне стейтрейсов и тех переменных, которые не убиты оптимизацией.

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

В терминах gcc это значит, что критичные модули могут быть скомпилированы с -O2 или -O3, а для остальных достаточно -Og (чтобы совсем уж жуткие случаи типа гоняния одного значения по 5 регистрам или, как у so5team@, несвёрнутые шаблоны — были устранены) или даже -O0 (для половины кода). Причём ни в условном Release вам не нужна оптимизация всех 99% некритичного кода, ни в Debug вам нельзя понижать уровень оптимизации критичного кода ниже -O или даже -O2 — он просто не сможет выполнять свои функции.

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

В результате получается, что да, у вас может быть несколько режимов сборки. Может, хоть 100 (ну или предположим 128): в зависимости от того, подробности какого из критичных модулей вам важнее для конкретного испытания. И ни один из них не должен становиться каноническим Debug (-O0 -g), ни каноническим Release (-O2 или -O3, к которому кроме отсутствия -g добавлен ещё и strip на итоговые бинарники).
Даже если какой-то из этих уровней, для простоты и общности, будет иметь название Debug или Release, его суть будет заметно другой.
Re[10]: Иллюстрация
Здравствуйте, night beast, Вы писали:

N>>Это очень просто. Выкиньте из головы прибитые там гвоздями представления про универсальный подход по опциям сборки на весь код. Дальше пойдёт легче.


NB>а зачем?

NB>если существующий подход нормально работает и используемые средства разработки под него заточены.

В том и дело, что не работает он "нормально". Или, если для вас "нормально" это случай этого героя интернета, то да, нормально — но очень быстро выходишь за пределы таких ограничений.

NB>что именно мы получаем от придуманных нами каких-то дополнительных уровней отладки/сборки?


У вас некая очень толстая программа со своей историей, которую ведёт достаточно разнообразная команда. Вам надо её улучшить — например, есть конкретное место, где вам надо ускорить (неважно что — отрисовку на экране, расчёт зарплаты, парсинг сетевого запроса, etc.)
Вы определили те модули/функции/методы, где происходит критичное по скорости выполнение.
Вам надо в этих модулях:
1. Вылизать код относительно всех плюх.
2. Установить для него максимум оптимизации. При этом, так как оптимизации начинают вызывать предположения компилятора, которые не соответствуют предположениям программиста (вспоминаем весь комплект ужастиков про undefined behavior с переполнениями, алиасингом и т.п.) — это будет смесь визуальной верификации и запусков санитайзеров, пока не будет достигнуто выполнение, которое адекватно по скорости и не вызывает жалобы на проблемы кода.
3. Установить на всех границах этого кода контроль значений (который в идеале никогда не должен выключаться).
После этого быть всё равно готовым к тому, что что-то пойдёт не так и надо иметь базовую информацию хотя бы на уровне стейтрейсов и тех переменных, которые не убиты оптимизацией.

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

В терминах gcc это значит, что критичные функции могут быть скомпилированы с -O2 или -O3, а для остальных достаточно -Og (чтобы совсем уж жуткие случаи типа гоняния одного значения по 5 регистрам или, как у so5team@, несвёрнутые шаблоны — были устранены) или даже -O0 (для половины кода). Причём ни в условном Release вам не нужна оптимизация всех 99% некритичного кода, ни в Debug вам нельзя понижать уровень оптимизации критичного кода ниже -O или даже -O2 — он просто не сможет выполнять свои функции.

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

В результате получается, что да, у вас может быть несколько режимов сборки. Может, хоть 100 (ну или предположим 128): в зависимости от того, подробности какого из критичных модулей вам важнее для конкретного испытания. И ни один из них не должен становиться каноническим Debug (-O0 -g), ни каноническим Release (-O2 или -O3, к которому кроме отсутствия -g добавлен ещё и strip на итоговые бинарники).
Даже если какой-то из этих уровней, для простоты и общности, будет иметь название Debug или Release, его суть будет заметно другой.