Compare commits
24 Commits
e36e9f8bbb
...
971107a38e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
971107a38e | ||
|
|
8a4d5e673a | ||
|
|
ffa3fc8b00 | ||
|
|
0d95d51d55 | ||
|
|
df0bbb0f4b | ||
|
|
72133bd71f | ||
|
|
c0d7ce44c7 | ||
|
|
dba60d8a77 | ||
|
|
49fa395a10 | ||
|
|
8d50afe15b | ||
|
|
719826c1a5 | ||
|
|
744f329f68 | ||
|
|
d648934dd3 | ||
|
|
9c0dd24b78 | ||
|
|
87c033da3a | ||
|
|
38b092b567 | ||
|
|
a2cb0a4ca1 | ||
|
|
1b00fb9950 | ||
|
|
fbe8ec627a | ||
|
|
e464dde870 | ||
|
|
e3aa74b1af | ||
|
|
0e5036527a | ||
|
|
993a601e21 | ||
|
|
380e1b0295 |
BIN
docs/linux/assets/distccmon-text.png
Normal file
BIN
docs/linux/assets/distccmon-text.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 255 KiB |
284
docs/linux/distrant.md
Normal file
284
docs/linux/distrant.md
Normal file
@@ -0,0 +1,284 @@
|
||||
# Немного про распределенную компиляцию
|
||||
|
||||
## Мотивация / Введение
|
||||
|
||||
Мне, как любителю Linux, всегда было интересно изучить Gentoo
|
||||
Linux. На это есть множество причин, сейчас не о них.
|
||||
Суть в том, этап установки системы на виртуальную машину пройден и
|
||||
есть желание попробовать установить на второстепенный маломощный нетбук.
|
||||
Возникает проблема: Gentoo Linux -- это т.н. "source-based" дистрибутив,
|
||||
т.е. она распространяется в виде исходного кода. В свою очередь, компиляция
|
||||
системы на нетбуке занимает чуть больше суток (возможно, это можно поправить
|
||||
более тщательной конфигурацией перед сборкой, но, на мой взгляд, это
|
||||
слишком "хардкорный" путь для знакомства с системой). Конечно, компиляция
|
||||
ядра, строго говоря, необязательна, так как можно поставить предварительно
|
||||
скомпилированную версию. Но так неинтересно.
|
||||
|
||||
Таким образом, возникает вопрос -- можно ли ускорить компиляцию
|
||||
на слабых ПК? Тут на помощь приходит `distcc`,
|
||||
своего рода фронтенд для компиляторов C/C++.
|
||||
|
||||
Сегодня мы хотим посмотреть на возможность компиляции ядра Linux (минимальной
|
||||
конфигурации `tinyconfig`) на двух виртуальных машинах с разными
|
||||
характеристиками. Но для этого нужно рассказать про утилиту `vagrant`,
|
||||
конфигуратор виртуальных машин.
|
||||
|
||||
## Vagrant
|
||||
|
||||
Vagrant[^1] (с англ. — «бродяга») — свободное и открытое программное
|
||||
обеспечение для создания и конфигурирования виртуальной среды разработки.
|
||||
Является обёрткой для программного обеспечения виртуализации, например
|
||||
VirtualBox, и средств управления конфигурациями, таких как Chef, Salt и
|
||||
Puppet.
|
||||
|
||||
Данная утилита полезна тем, что позволяет, используя шаблоны виртуальных
|
||||
машин, запускать их. Для описания стэка требуется один т.н. Vagrantfile.
|
||||
Она может работать совместно с qemu, VirtualBox, VMWare и пр.
|
||||
|
||||
О vagrant стоит знать потому, что в какой момент, эксперементируя с
|
||||
виртуальными машинами, надоест каждый раз их устанавливать в условном VMWare.
|
||||
|
||||
## Distcc
|
||||
|
||||
distcc[^2] (от англ. distributed C/C++/ObjC compiler) — инструмент,
|
||||
позволяющий компилировать исходные коды при помощи
|
||||
компиляторов C/C++/ObjC на удалённых машинах, что ускоряет процесс компиляции.
|
||||
|
||||
Важно понимать, что это своего рода фронтенд для компиляторов,
|
||||
сам по себе он не компилирует код.
|
||||
|
||||
## Компиляция
|
||||
|
||||
### Демонстрация стенда
|
||||
|
||||
Для начала построчно рассмотрим 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)
|
||||
с исходным кодом ядра (должен лежать в директории с Vagrantfile).
|
||||
|
||||
Конфигурация второстепенных машин:
|
||||
|
||||
```
|
||||
# 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` и далее. Сделано это на случай нескольких ВМ.
|
||||
|
||||
### Компиляция на одной машине (gcc)
|
||||
|
||||
Для начала запустим стенд командой `vagrant up`. На моем ноутбуке это занимает
|
||||
примерно 127 секунд.
|
||||
|
||||
Далее необходимо подключиться к главной машине и распаковать исходники ядра[^3]:
|
||||
|
||||
```
|
||||
vagrant ssh master
|
||||
tar xvf linux-6.13.tar.gz
|
||||
cd linux-6.13
|
||||
```
|
||||
|
||||
Создаем файл минимальной конфигурации
|
||||
(с остальными вариантам можно ознакомиться командой `make help | less`):
|
||||
|
||||
```
|
||||
make tinyconfig
|
||||
```
|
||||
|
||||
> **Важно**: для чистоты эксперимента все замеры делаются после команды `make
|
||||
distclean` (см. `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
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Таблица сравнения
|
||||
|
||||
|Итерация|Одна машина (gcc), с|Одна машина (distcc), с|Две машины (distcc), с|
|
||||
|:------:|:------------------:|:---------------------:|:--------------------:|
|
||||
| 1 | 176 | 176 | 111 |
|
||||
| 2 | 186 | 162 | 109 |
|
||||
| 3 | 187 | 174 | 127 |
|
||||
|Среднее | 183 | 170 | 115 |
|
||||
|
||||
## Итог
|
||||
|
||||
Можно увидеть, что такая параллелизация дает прирост 37%.
|
||||
Сложно сказать, можно ли разогнать сильнее, так как многое зависит от
|
||||
правил компиляции (например, их нельзя распараллелить больше чем на 5 потоков).
|
||||
|
||||
Очевидно, что распределенная компиляция при прочих равных будет проигрывать
|
||||
параллельной, так как общение между потоками по определению быстрее.
|
||||
Но для слабых машин это отлично подходит. К сожалению, у данного метода есть
|
||||
существенные ограничения:
|
||||
|
||||
1. Версии gcc и distcc должны совпадать (хотя, пишут, что достаточно
|
||||
совпадения только мажорных версий).
|
||||
2. В некоторых случаях нет возможности общения по TCP и требуется подключение по
|
||||
SSH. Например, когда есть ограничения безопасности или при сложной организации
|
||||
сети. Определенно, такое подключение будет медленнее.
|
||||
|
||||
Все материалы стенда можно найти в
|
||||
[репозитории](https://github.com/rustbas/disgrant/) на Github.
|
||||
|
||||
[^1]: Википедия [Vagrant](https://ru.wikipedia.org/wiki/Vagrant).
|
||||
[^2]: Википедия [distcc](https://ru.wikipedia.org/wiki/Distcc).
|
||||
[^3]: Исходный код ядра можно найти [здесь](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz).
|
||||
@@ -2,3 +2,5 @@
|
||||
|
||||
## 2024-11-01 [Немного про мануалы](manpage.md)
|
||||
|
||||
## 2025-01-24 [Немного про распределенную компиляцию](distrant.md)
|
||||
|
||||
|
||||
BIN
docs/maths/assets/stat-madness/bootstrap.png
Normal file
BIN
docs/maths/assets/stat-madness/bootstrap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
BIN
docs/maths/assets/stat-madness/conf_interval.png
Normal file
BIN
docs/maths/assets/stat-madness/conf_interval.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
BIN
docs/maths/assets/stat-madness/modeling.png
Normal file
BIN
docs/maths/assets/stat-madness/modeling.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
@@ -6,3 +6,5 @@
|
||||
|
||||
## 2024-09-24 [Немного про Байесовскую статистику](baes.md)
|
||||
|
||||
## 2020-09-01 [Немного про проверку гипотез](stat-madness.md)
|
||||
|
||||
|
||||
199
docs/maths/stat-madness.md
Normal file
199
docs/maths/stat-madness.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Немного про проверку гипотез
|
||||
|
||||
## Введение
|
||||
|
||||
Любые статистические испытания зиждятся на проверке гипотез, например:
|
||||
|
||||
1. Проверка действия лекарств.
|
||||
2. Установление зависимости между явлениями.
|
||||
3. A/B тестирование и пр.
|
||||
|
||||
В зависимости от вида данных, целей исследования и других факторов
|
||||
можно по-разному формулировать гипотезы и по-разному их проверять.
|
||||
|
||||
Многое зависит от не только знаний и опыта исследователя, но и в целом
|
||||
от его подхода. В процессе работы можно все меньше уделять внимание
|
||||
математической составляющей и все больше полагаться на компьютер и его
|
||||
вычислительные мощности.
|
||||
|
||||
Здесь я хочу рассказать о стадиях, через которые проходит исследователь,
|
||||
в попытках упростить себе жизнь и ускорить процесс проверки гипотез.
|
||||
|
||||
## Небольшой ликбез
|
||||
|
||||
В статистике, если упростить, проверку гипотезы можно описать так:
|
||||
|
||||
1. По данной выборке считается статистика (т.е. функция от выборки).
|
||||
2. Из распределения статистики находятся две области, где гипотеза отвергается и где нет. Исходя из этого, принимается решение.
|
||||
|
||||
**N.B.** Проверяется гипотеза, модель постулируется.
|
||||
|
||||
## Стадия 1. Строгие доказательства
|
||||
|
||||
На данной стадии ученый строго выводит распределения статистик, чтобы построить как можно более хорошие критерии.
|
||||
|
||||
$$\Large
|
||||
\sqrt{n}
|
||||
\frac
|
||||
{\overline{\mathbb{X}} - \mu}
|
||||
{S} =
|
||||
\sqrt{n}
|
||||
\frac
|
||||
{\overline{\mathbb{X}} - \mu}
|
||||
{\sigma} \cdot
|
||||
\frac{1}
|
||||
{\frac{S}{\sigma}} =
|
||||
$$
|
||||
|
||||
$$\Large
|
||||
= \sqrt{n}
|
||||
\frac
|
||||
{\overline{\mathbb{X}} - \mu}
|
||||
{\sigma} \cdot
|
||||
\frac{1}
|
||||
{\sqrt{\frac{(n-1)S^2}{\sigma^2}\cdot
|
||||
\frac{1}{n-1}
|
||||
}}
|
||||
$$
|
||||
|
||||
Получим:
|
||||
|
||||
$$\Large
|
||||
\begin{matrix}
|
||||
&\sqrt{n}
|
||||
\frac{\overline{\mathbb{X}} - \mu}
|
||||
{\sigma} &\sim &N(0,1) \\
|
||||
&\frac{(n-1)S^2}{\sigma^2} &\sim &\chi^2(n-1)
|
||||
\end{matrix}
|
||||
$$
|
||||
|
||||
Таким образом, по [определению](https://ru.wikipedia.org/wiki/Распределение_Стьюдента#Определение):
|
||||
|
||||
$$\Large
|
||||
\sqrt{n}
|
||||
\frac
|
||||
{\overline{\mathbb{X}} - \mu}
|
||||
{S} \sim t(n-1).
|
||||
$$
|
||||
|
||||
## Небольшой пример (критерий Стьюдента)
|
||||
|
||||
**Дано**: выборка Х объема 10
|
||||
|
||||
$$\Large
|
||||
\mathbb{X} = \left(
|
||||
\begin{matrix}
|
||||
3.175 \\
|
||||
4.042 \\
|
||||
2.127 \\
|
||||
3.841 \\
|
||||
1.699 \\
|
||||
2.223 \\
|
||||
3.211 \\
|
||||
3.33 \\
|
||||
2.447 \\
|
||||
2.904
|
||||
\end{matrix}
|
||||
\right)
|
||||
$$
|
||||
|
||||
**Модель**: $N(\mu, \theta_2)$
|
||||
|
||||
**Нулевая гипотеза**: $\mu = 3$
|
||||
|
||||
**Решение**:
|
||||
|
||||
Статистика критерия:
|
||||
|
||||
$$\Large
|
||||
T(\mathbb{X}) =
|
||||
\sqrt{n}
|
||||
\frac
|
||||
{\overline{\mathbb{X}} - \mu}
|
||||
{S}
|
||||
\sim
|
||||
t(n-1)
|
||||
$$
|
||||
|
||||
Статистика равна:
|
||||
|
||||
$$\Large
|
||||
T(\mathbb{X}) = -1.9066
|
||||
$$
|
||||
|
||||
Пусть уровень значимости $\alpha = 0.05$.
|
||||
|
||||
Область, где не отвергается нулевая гипотеза: $(g_1, g_2) = (-2.262, 2.262)$, т.е. это область, которую принимает значение статистики при условии верности нулевой гипотезы с вероятностью $1 - \alpha = 0.95$. $g_1$ в данном случае это $0.025$-квантиль, а $g_2$, соотвественно, 0.975-квантиль.
|
||||
|
||||

|
||||
|
||||
Красным обозначен интервал $(g_1, g_2)$
|
||||
|
||||
Таким образом, нулевая гипотеза не отвергается, так как значение статистики лежит в данном интервале.
|
||||
|
||||
> **Примечание**: можно было выбрать доверительный интервал иначе,
|
||||
> но его стараются выбрать так, чтобы минимизировать его длину.
|
||||
|
||||
## Стадия 2. Открытие моделирования
|
||||
|
||||
Иногда (вернее, даже как правило) распределение статистики вывести
|
||||
невозможно. В таком случае пользуются моделированием. Идея в том, что
|
||||
нам известно распределение выборки в случае нулевой гипотезы. Таким
|
||||
образом, можно многократно генерировать выборки и считать статистику,
|
||||
таким образом получив ее распределение.
|
||||
|
||||

|
||||
|
||||
В данном случае, моделирование выборки проводилось
|
||||
в условиях $X \sim N(\mu, S^2)$.
|
||||
|
||||
Можно увидеть некоторое расхождение. В этом, кстати, заключается интересный
|
||||
момент. Часто критикуются исследования построенные на моделировании, так как
|
||||
есть ненулевая (хоть и очень маленькая) вероятность, что выборки
|
||||
сгенерировались так, что полученное распределение статистики плохо отражает
|
||||
реальность.
|
||||
|
||||
## Стадия 3. Бутстрэп
|
||||
|
||||
Бывают случаи, когда распределение выборки неизвестно совсем
|
||||
(или его сложно/нельзя в обычном смысле генерировать,
|
||||
[пример](https://stepik.org/lesson/40491/step/1?unit=24794)). В таком случае
|
||||
постулируют, что данная выборка хорошо отражает генеральную совокупность и в
|
||||
качестве функции распределения берут эмпирическую функцию распределения.
|
||||
|
||||
$$\Large
|
||||
F_n(x) = \frac
|
||||
{\sum_{i=1}^{n} \mathbb{1}(x)}
|
||||
{n}
|
||||
$$
|
||||
|
||||
где:
|
||||
|
||||
$$\Large
|
||||
\mathbb{1}(x) =
|
||||
\begin{cases}
|
||||
1, x > X_i, \\
|
||||
0, \text{ иначе.}
|
||||
\end{cases}
|
||||
$$
|
||||
|
||||
В итоге, получается, что для проверки гипотез не нужно ничего кроме выборки и выдуманной статистики (которая, вообще, может быть любой, от нее зависит только качество получаемого критерия).
|
||||
|
||||
Основная идея заключается в том, чтобы генерировать выборки объемом как и данная выборка из следующего распределения:
|
||||
|
||||
$$\Large
|
||||
\mathcal{F} =
|
||||
\begin{pmatrix}
|
||||
X_1 &X_2 &\cdots &X_n \\
|
||||
\frac{1}{n} &\frac{1}{n} &\cdots &\frac{1}{n}
|
||||
\end{pmatrix}.
|
||||
$$
|
||||
|
||||

|
||||
|
||||
Таким образом, из расхождения графиков можно сделать следующие выводы:
|
||||
|
||||
- применение бутстрэпа требует большой объема первоначальной выборки,
|
||||
- наблюдения в выборке должны быть независимыми.
|
||||
|
||||
Несмотря на это, он часто применяется невпопад, так как не требует особых затрат на реализацию.
|
||||
Reference in New Issue
Block a user