From c0d7ce44c79c033e32797c250a16adfe36179c44 Mon Sep 17 00:00:00 2001 From: Basyrov Rustam Date: Fri, 24 Jan 2025 11:15:29 +0300 Subject: [PATCH] article --- docs/linux/distrant.md | 248 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 239 insertions(+), 9 deletions(-) diff --git a/docs/linux/distrant.md b/docs/linux/distrant.md index e71f933..75a9aa0 100644 --- a/docs/linux/distrant.md +++ b/docs/linux/distrant.md @@ -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%