This commit is contained in:
Basyrov Rustam
2025-01-24 11:15:29 +03:00
parent dba60d8a77
commit c0d7ce44c7

View File

@@ -1,6 +1,9 @@
# Немного про распределенную компиляцию
> В телеграмме про распределенные и параллельные вычисления
> В конце про версии `gcc`
> В конце ссылка на репозиторий
> В итоге про tcp и ssh
## Мотивация / Введение
@@ -26,18 +29,245 @@ Linux. На это есть множество причин, сейчас не
## Vagrant
- Польза для сисадмина
- Создание стендов
- Декларативный стиль работы с виртуальными машинами
Vagrant[^1] (с англ. — «бродяга») — свободное и открытое программное
обеспечение для создания и конфигурирования виртуальной среды разработки.
Является обёрткой для программного обеспечения виртуализации, например
VirtualBox, и средств управления конфигурациями, таких как Chef, Salt и
Puppet.
Данная утилита полезна тем, что позволяет, используя шаблоны виртуальных
машин, запускать их. Для описания стэка требуется один т.н. Vagrantfile.
Она может работать совместно с qemu, VirtualBox, VMWare и пр.
О vagrant стоит знать потому, что в какой момент, эксперементируя с
виртуальными машинами, надоест каждый раз их устанавливать в условном VMWare.
## Distcc
- Распределенная компиляция
distcc[^2] (от англ. distributed C/C++/ObjC compiler) — инструмент,
позволяющий компилировать исходные коды при помощи
компиляторов C/C++/ObjC на удалённых машинах, что ускоряет процесс компиляции.
## Компиляция
- Демонстрация стенда
- Компиляция на одной машине (gcc)
- Компиляция на одной машине (distcc)
- Компиляция на нескольких машинах (distcc)
- Таблица сравнения
- [x] Демонстрация стенда
- [ ] Компиляция на одной машине (gcc)
- [ ] Компиляция на одной машине (distcc)
- [ ] Компиляция на нескольких машинах (distcc)
- [ ] Таблица сравнения
### Демонстрация стенда
Для начала построчно рассмотрим Vagrantfile.
Используется язык Ruby.
Описание "шаблона" для виртуальных машин. В данном случае это Debian
12 Bookworm.
```ruby
# Default box
box_name = "debian.jessie64.libvirt.box"
```
Файл можно скачать с сайта HashiCorp.
Описание виртуальной машины, на которой будет основная компиляция:
```
# Master
master_node = {
:hostname => "master", :ip => "10.200.1.2", :memory => 1024, :cpu => 1
}
```
Характеристики:
- IP: 10.200.1.2
- RAM: 1Gb
- 1 поток
Это почти похоже на характеристики моего нетбука, но они занижены
в целях демонстрации.
Описание второстепенной виртуальной машины:
```
# List of slaves
slaves = [
{ :memory => 4096, :cpu => 4 },
]
```
Характеристики:
- RAM: 4Gb
- 4 потока
Скрипт для автоматической установки зависимостей:
```
$distcc_install = <<-SCRIPT
apt update
apt install -y make distcc gcc g++ tmux libz-dev git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison time neofetch
SCRIPT
```
Старт конфигурации виртуальных машин:
```
Vagrant.configure("2") do |config|
```
Конфигурация основной машины:
```
# Master node's config
config.vm.box_check_update = false
config.vm.define master_node[:hostname] do |nodeconfig|
nodeconfig.vm.box = box_name
nodeconfig.vm.hostname = master_node[:hostname]
nodeconfig.vm.network(:private_network, ip: master_node[:ip])
nodeconfig.vm.provision "shell", inline: $distcc_install
nodeconfig.vm.provision "file", source: "./linux-6.13.tar.gz", destination: "~/linux-6.13.tar.gz"
nodeconfig.vm.provider :libvirt do |vb|
vb.memory = master_node[:memory]
vb.cpus = master_node[:cpu]
end
end
```
В нем:
1. Отключаются обновления,
2. Задаются характеристики ВМ,
3. Запускается скрипт установки зависимостей,
4. Копируется
[архив](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz)
с исходным кодом ядра.
Конфигурация второстепенных машин:
```
# Slaves configs
slaves.each_with_index do |slave, i|
config.vm.box_check_update = false
config.vm.define "slave-#{ i+1 }" do |nodeconfig|
# Default box-name (cause I have only it)
nodeconfig.vm.box = box_name
# Hostname: slave-N
nodeconfig.vm.hostname = "slave-#{ i+1 }"
# IP-address: 10.200.1.{N+2}
nodeconfig.vm.network :private_network, ip: "10.200.1.#{ i+3 }"
nodeconfig.vm.provision "shell", inline: $distcc_install
nodeconfig.vm.provider :libvirt do |vb|
vb.memory = slave[:memory]
vb.cpus = slave[:cpu]
end
end
end
end
```
Стоит обратить внимание, что IP задается автоматически, начиная от
`10.200.1.3` и далее. Сделано это на случай нескольких ВМ.
### Компиляция на одной машине
Для начала запустим стенд командой `vagrant up`. На моем ноутбуке это занимает
примерно __ секунд.
Далее необходимо подключиться к главной машине и распаковать исходники ядра:
```
vagrant ssh master
tar xvf linux-6.13.tar.gz
cd linux-6.13
```
Создаем файл минимальной конфигурации
(с остальными вариантам можно ознакомиться командой `make help | less`):
```
make tinyconfig
```
> **Важно**: для чистоты эксперимента все замеры делаются после команды `make
clean` (см. `make help`).
Запускаем компиляцию с замером времени:
```
time -p make CC=gcc
```
### Одна машина (distcc)
По смыслу, все тоже самое, только нужно указать distcc, на каких хостах
можно компилировать:
```sh
export DISTCC_HOSTS="localhost"
```
Запускаем компиляцию с замером времени:
```
time -p make CC="distcc gcc"
```
### Две машины (distcc)
Для запуска распределенной компиляции, нужно сначала запустить демон на
второй виртуальной машине. Для этого подключаемся к ней и запускаем его:
```
vagrant ssh slave-1
distccd --daemon --allow-private
```
Параметр `--allow-private` разрешает стучаться только с приватных сетей.
Для проверки можно:
1. На второй машине проверить открытые порты: `ss -ntlp | grep 3632`
2. На основной машине постучаться в этот порт: `telnet 10.200.1.3 3632`
(выход на `C-] C-d`)
Теперь нужно добавить хост, чтобы на нем можно было удаленно компилировать.
Для этого на основной машине:
```
export DISTCC_HOSTS="localhost 10.200.1.3"
```
Для проверки можно посмотреть список хостов для компиляции: `distcc --show-hosts`.
Запустим компиляцию на 5 потоках с замером времени:
```sh
time -p make -j5 CC="distcc gcc"
```
Мониторить компиляцию можно с помощью команды (на основной машине):
```
watch -n 1 distccmon-text
```
![distccmon-text](assets/distccmon-text.png)
### Таблица сравнения
|Итерация|Одна машина (gcc), с|Одна машина (distcc), с|Две машины (distcc), с|
|:------:|:------------------:|:---------------------:|:--------------------:|
| 1 | 176 | 176 | 111 |
| 2 | 186 | 162 | 109 |
| 3 | 187 | 174 | 127 |
|Среднее | 183 | 170 | 115 |
[^1]: Википедия [Vagrant](https://ru.wikipedia.org/wiki/Vagrant).
[^2]: Википедия [distcc](https://ru.wikipedia.org/wiki/Distcc).
## Итог
37%