Тут собраны небольшие учебные программы на MPI (много процессов, обмениваются сообщениями) и OpenMP (один процесс, много потоков).
Представьте, что вы запустили программу не один раз, а много одинаковых копий одновременно. Каждая копия — это процесс.
size— сколько процессов всего (например,mpirun -np 4 ...⇒size = 4).rank— номер конкретного процесса:0, 1, 2, ..., size-1.- Обычно
rank = 0делают “главным” (root): он формирует входные данные, собирает результат и печатает.
Это “группа всех процессов”, которые вы запустили вместе. Почти все примеры работают именно в ней.
Запуск MPI-среды. Без этого MPI не работает. Всегда в начале.
Даёт текущему процессу его номер (rank). У каждого процесса свой.
Говорит, сколько процессов в группе (size). Одинаково у всех.
“Ждём друг друга”. Пока все процессы не дойдут до барьера — никто дальше не идёт. Зачем обычно нужно:
- чтобы ровно начать замер времени
- чтобы вывод не превращался в кашу
Это “отправить сообщение” и “получить сообщение”.
Очень простая идея:
MPI_Send— процесс A отправляет массив данных процессу B.MPI_Recv— процесс B ждёт и принимает эти данные в свой буфер.
Параметры, которые важно понимать:
dest(вSend) — кому отправляем (rank получателя)source(вRecv) — от кого ждём (rank отправителя)tag— “ярлык” сообщения, чтобы не перепутать разные типы сообщений. Например, в одной программе можно пересылать несколько разных вещей — tag помогает отличать их.
Важно: если один процесс “ждёт” (Recv), а ему никто не отправляет — он будет ждать бесконечно.
Корректное завершение MPI. Всегда в конце.
- Пример с
MPI_Alltoall: каждый процесс рассылает куски своего массива всем процессам и получает куски от всех. - Пример с
MPI_Scatterv + MPI_Allgatherv:- root делит один большой вектор на куски (кусок может быть разной длины)
- раздаёт куски всем процессам (
Scatterv) - потом собирает исходный вектор на каждом процессе (
Allgatherv)
В этих программах есть вспомогательные функции, которые специально делают упорядоченный вывод, чтобы строки от разных процессов не перемешивались.
MPI_Reduce с операцией MPI_PROD: каждый процесс имеет небольшой вектор, и root получает результат “поэлементно перемножить значения всех процессов”.
Сортировка столбцов матрицы:
- root создаёт матрицу
- каждый столбец “отдаётся” какому-то процессу (по правилу
col % size) - процесс сортирует свой столбец и возвращает обратно
- root собирает столбцы обратно в матрицу
Поиск максимума в векторе:
- сначала считается максимум последовательно (для контроля)
- потом параллельно с
reduction(max: ...) - результаты сравниваются
Сортировка строк матрицы 70x90:
- каждая строка сортируется независимо, значит можно распараллелить цикл по строкам
- делается последовательный “эталон” и параллельный вариант, потом сравнение
- дальше идёт интерактивный цикл: вводите номер строки и смотрите всю строку до/после сортировки
- MPI: обычно
mpic++ ...внутри папки лабораторной. - OpenMP на macOS: чаще всего нужен
brew install libomp, затем сборка черезclang++ -Xpreprocessor -fopenmp ... -lomp.