Ускорение компиляции в Linux используя ccache и distcc

Опубликовано:

Тем кто использует такие операционные системы как Gentoo и FreeBSD пакеты ccache и distcc должны быть хорошо знакомы, те кто использует бинарные дистрибутивы так же могли о них слышать.

Ccache — кеш C/C++ компиляторов. При компилировании какого-либо файла вычисляется его хэш, если файл с таким хэшем есть в локальном кеше, то файл не будет повторно компилироваться, вместо этого будет использован файл из кеша. Так как при обновлении программы, как правило, изменяются не все файлы исходного кода, использование кеша позволяет существенно ускорить не только повторную компиляцию программы, но и ее обновлений.

Distcc — позволяет компилировать исходные коды C/C++/ObjC на нескольких компьютерах. Поддерживает кросс-платформенное компилирование. Для отсутствия ошибок в программ скомпилированных посредством distcc на всех компьютерах должна быть установлена одинаковая версия gcc, например 4.3.x, при этом x — может отличаться.

Рассмотрим установку и настройку ccache и distcc в бинарном дистрибутиве, на примере Debian Linux. Некоторые могут сказать, подобные программы в бинарном дистрибутиве не нужны, в общем то это справедливо, но только до тех пор, пока не требуется использование apt-build, make-kpkg и вас полностью устраивает набор ПО и их версий включенных в текущий релиз.

Пакеты ccache и distcc включены в стандартные репозитории Debian, поэтому их установка сводится к выполнению одной команды:

root@localhost:~$ apt-get install ccache distcc

Настройка Ccache

Чтобы начать использовать ccache во время компиляции нужно установить несколько переменных окружения, сделаем это через .profile или .bashrc, добавим такие строки:

export PATH=/usr/lib/ccache:$PATH
export CC="ccache gcc"
export HOSTCC="ccache gcc"
export HOSTCXX="ccache g++"
export CCACHE_DIR="/var/cache/.ccache"

Переменная CCACHE_DIR — устанавливает каталог где хранится кеш C/C++ компиляторов, по умолчанию она равна $HOME/.ccache.

Настройка Distcc

Данная будет полезна только тем у кого в распоряжении есть несколько компьютеров с одной версией gcc, например ПК и ноутбук, или ноутбук или домашний сервер.

Все настройки демона distcc в Debian находятся в файле /etc/default/distcc:

 
STARTDISTCC="true"
 
ALLOWEDNETS="127.0.0.1 192.168.0.0/24"
 
LISTENER="0.0.0.0"
 
JOBS="4"

Число джобов не должно быть больше числа ядер:

root@localhost:~$ cat /proc/cpuinfo |grep processor |wc -l
4

Таким образом следует настроить distcc на каждом хосте. После настройки демонов их нужно запустить:

root@localhost:~$ invoke-rc.d distcc start

Теперь клиентская часть, в .profile или .bashrc, добавим:

export CCACHE_PREFIX="distcc"
export CONCURRENCY_LEVEL=7
export DISTCC_HOSTS="localhost/3 192.168.0.2/2 192.168.0.3/2"

В переменной DISTCC_HOSTS указывается перечень хостов, через слеш указывается максимальное число параллельных задач компиляции которое может быть принято хостом, кроме того, если хост находится не в локальной сети, есть смысл включить lzo-компрессию. Для локальной машины стоит указать число задач на 1 меньше максимального, так как, кроме непосредственно процесса компиляции, она будет обрабатывать задачи отправляемые на удаленные хосты посредством distcc.
Переменная CONCURRENCY_LEVEL устанавливает максимальное число параллельных задач компиляции в момент времени.

На последок, немного практики, соберем ядро Linux 2.6.36 на копьютере с процессором Intel Atom D510:

root@localhost:/usr/src/linux-2.6.36$ time make-kpkg --initrd --revision=atom1 kernel_image
kernel_headers
...
real	64m37.225s
user	135m48.470s
sys	27m38.509s

Подчистим за собой

root@localhost:/usr/src/linux-2.6.36$ make mrproper
root@localhost:/usr/src/linux-2.6.36$ make-kpkg clean

И соберем ядро еще раз:

root@localhost:/usr/src/linux-2.6.36$ time make-kpkg --initrd --revision=atom1 kernel_image
kernel_headers
...
real	21m36.359s
user	31m15.794s
sys	12m5.879s

Статистика ccache выглядит при этом примерно так:

root@localhost:/usr/src/linux-2.6.36$ ccache -s
cache directory                     /var/ccache/.ccache
cache hit (direct)                 17112
cache hit (preprocessed)              18
cache miss                          8624
called for link                      110
unsupported source language          117
unsupported compiler option         4494
no input file                       4224
files in cache                     25844
cache size                           1.5 Gbytes
max cache size                       2.0 Gbytes

Понравилась статья, расскажи о ней друзьям, нажми кнопку!