This commit is contained in:
lovinervy committed 2026-10-07 13:06:47 +05:00
commit c394677d07
59 files changed
+5149

No files matched your search

+140
View File
@@ -0,0 +1,140 @@
# Лабораторная работа 8. Распределённые вычисления (MPI)
**Время на работу:** 2–3 пары. **Зависимости:** лабы 1, 4.
## Цель работы
Освоить модель передачи сообщений (MPI) — стандарт распределённых вычислений,
на котором работают суперкомпьютеры. Понять отличие «общей памяти»
(потоки/процессы Python) от «обмена сообщениями» между независимыми узлами.
## Теория
### Модель MPI
MPI (Message Passing Interface) — набор программ на нескольких **узлах**
(машинах или процессах), обменивающихся сообщениями. Нет общей памяти: любые
данные передаются явно, функциями отправки/приёма. Программа запускается
одновременно на N «рангах» (процессах):
```bat
mpiexec -n 4 python script.py # 4 копии script.py
```
Каждая копия узнаёт, кто она:
```python
from mpi4py import MPI
comm = MPI.COMM_WORLD # «мир» — все ранги
rank = comm.Get_rank() # мой номер: 0..size-1
size = comm.Get_size() # всего рангов
```
Ранг 0 обычно координатор: он делит работу и собирает результат.
### Операции: «точка-точка» и коллективные
**Точка-точка** (ранг ↔ ранг):
```python
comm.send(data, dest=1, tag=0) # блокирующая отправка
data = comm.recv(source=0, tag=0) # блокирующий приём
```
**Коллективные** (все ранги сразу — проще и обычно быстрее):
| Операция | Что делает |
|---|---|
| `bcast` | один раздает всем (broadcast) |
| `scatter` | список режется на части: ранг i получает i-ю часть |
| `gather` | части собираются в список на одном ранге |
| `reduce` | части сворачиваются операцией (sum/max/…) на одном ранге |
| `barrier` | все ждут, пока все дойдут до этой точки |
### Схема параллельной задачи в MPI
```
ранг 0: build -> split -> scatter ─┐
ранги 1..N: получают кусок │-> kernel -> gather -> combine -> checksum
ранг 0: собирает ┘
```
Это ровно ваша схема split→kernel→combine из лаб 1–4, только обмен данными —
через сеть/IPC, а не общую память.
### Установка (Windows)
1. MS-MPI: скачать и установить **msmpisetup.exe** и **msmpires.msi**
(https://www.microsoft.com/en-us/download/details.aspx?id=105289).
2. `pip install mpi4py`
3. Проверка: `mpiexec -n 2 python -c "from mpi4py import MPI; print(MPI.COMM_WORLD.Get_rank())"`
На macOS/Linux: `brew install open-mpi` / `apt install libopenmpi-dev`,
затем `pip install mpi4py`, запуск `mpiexec` (или `mpirun`).
Важно: запускать `mpiexec -n 4` — тогда `solution.py` выполнится 4 раза
параллельно. Запуск без mpiexec допустим: программа работает как один ранг
(полезно для отладки и автотестов).
## Задание
Заполните `solution.py`:
1. **`mpi_run(task_name, params)`** — параллельное выполнение вашей CPU-задачи:
ранг 0 строит данные и делит на `size` кусков, `scatter` раздаёт,
каждый ранг считает `kernel` (используя `dispatch_kernel` не нужно —
в MPI функции не пиккелятся, только данные), `gather` собирает,
ранг 0 возвращает checksum. Для задачи «Жизнь» — цикл по поколениям
(см. подсказку в заготовке).
2. **`mpi_pi(N)`** — учебный пример: π методом Монте-Карло на всех рангах,
сборка через `reduce` (сумма попаданий). Каждый ранг использует
`random.Random(100 + rank)` — свои броски.
3. **`main()`** — checksum и время `mpi_run` на текущем числе рангов
(`size`), печать с ранга 0. Запустите при `-n 1, 2, 4` — получите T(p).
### Ожидаемые результаты
- checksum совпадает с последовательным запуском (лаба 1).
- T(p) на одном компьютере ≈ результатам multiprocessing из лабы 4
(плюс небольшие расходы на обмен).
- На настоящих нескольких машинах код не меняется — меняется только
запуск (это главный смысл MPI).
### Измерения для отчёта
```bat
mpiexec -n 1 python lab08_mpi\solution.py
mpiexec -n 2 python lab08_mpi\solution.py
mpiexec -n 4 python lab08_mpi\solution.py
```
## Контрольные вопросы
1. Чем модель передачи сообщений отличается от модели общей памяти?
2. Что делает `scatter` и чем она отличается от `bcast`?
3. Почему в MPI функции не нужно пиккелить, а в multiprocessing — нужно?
4. Что такое ранг? Как ранг 0 узнаёт, сколько всего рангов?
5. Когда MPI выгоднее multiprocessing, даже на одном компьютере?
## Что сдаётся
`solution.py` + отчёт: вывод при `-n 1/2/4`, таблица T(p), сравнение с
лабой 4, ответы на вопросы.
## Критерии оценки
| Пункт | Баллы |
|---|---|
| mpi_run: checksum корректен при -n 1 и -n 4 | 3 |
| mpi_pi через reduce | 2 |
| Замеры при разном числе рангов | 2 |
| Отчёт и ответы на вопросы | 3 |
## Типичные ошибки
- Код с веткой «если rank == 0» выполняется ВСЕМИ рангами — не заворачивайте
всю программу в `if rank == 0`.
- Разные random на разных рангах без фиксации зерна — невоспроизводимый
результат.
- Заблокированный `recv` без парной `send` — программа висит. Начинайте с
коллективных операций, они безопаснее.