#опытным
Как только ваш проект достигает определенного размера, время компиляции начинает становиться проблемой. В моей скромной практике были проекты, которые полностью собирались с 1-2 часа. Но это далеко не предел. Пишите кстати в комментах ваши рекордные тайминги сборки проектов.
С этим жить, конечно, очень затруднительно. Даже инкрементальная компиляция может занимать десятки минут. Как разрабатывать, когда большая часть времени уходит на билд? Кто-то безусловно будет радоваться жизни и попивать кофеек, если не пивко, пока билд билдится. Но компании это не выгодно, поэтому кто-то должен озаботится этой проблемой. То есть вам необходимо найти эффективные способы сократить это время, чтобы свести к минимуму периодические задержки и максимизировать продуктивность.
Есть разные способы достичь этой цели, один уже рассмотрели. Но сегодня мы поговорим распределенную компиляцию.
Основная идея распределенной компиляции такова: поскольку единицы трансляции обычно можно компилировать независимо друг от друга, существует огромный потенциал для распараллеливания. Это значит, что вы можете использовать множество потенциально удаленных CPU для того, чтобы нагрузка компиляции распределялась между этими юнитами вычисления.
Так как обычно девелоперские задачи в среднем потребляют мало ресурсов(не так много нужно, чтобы писать буквы в редакторе), этими удаленными CPU могут быть даже машины ваших коллег!
Наиболее известный представитель систем распределенной компиляции с открытым исходным кодом — это
distcc. Он состоит из демона-сервера, принимающего задания на сборку по сети, и обёртки (wrapper) для компилятора, которая распределяет задания по доступным узлам сборки в сети. Вот примерная схема его работы(у кого-то может некорректно отображаться, ничего поделать не можем):
┌─────────────────┐ ┌─────────────────────────────────┐
│ Клиентская │ │ Ферма компиляции │
│ машина │ │ │
│ │ │ ┌───────┐ ┌───────┐ ┌───────┐│
│ ┌─────────────┐│ │ │Worker │ │Worker │ │Worker ││
│ │ Координатор │◄──────►│ 1 │ │ 2 │ │ N ││
│ └─────────────┘│ │ └───────┘ └───────┘ └───────┘│
│ │ │ │
│ ┌─────────────┐│ │ ┌─────────────────────────────┐│
│ │ Кэш .o ││ │ │ Distributed Cache ││
│ │ файлов │◄──────►│ ││
│ └─────────────┘│ │ └─────────────────────────────┘│
└─────────────────┘ └─────────────────────────────────┘
- Координатор анализирует зависимости между файлами и распределяет задачи компиляции
- Компиляционные ноды выполняют фактическую компиляцию, их набор конфигурируется на клиенте
- Распределенный кэш хранит скомпилированные объектные файлы, кэширует результаты компиляции, тем самым ускоряя повторные сборки
Этапы работы примерно такие:
1️⃣ Все цппшники проекта проходят этап препроцессинга на локальной машине и уже в виде единиц трансляции перенаправляются на ноды компиляции.
2️⃣ Ноды компиляции преобразуют единицы трансляции в объектные файлы и пересылают их на клиентскую машину.
3️⃣ Последним этапом идет бутылочное горлышко всей системы - линковка. Для нее необходим доступ ко многим объектым файлам одновременно и эта задача слабо параллелится, поэтому и выполняется на клиентской машине.
Таким образом вы можете уменьшить время сборки проекта в разы и ускорить разработку в целом. Вот ссылочка на доку для заинтересовавшихся.
Speed up processes. Stay cool.
#compiler #tools