- •Лекция 1 Классификация многопроцессорных систем
- •Сетевой закон Амдала
- •Лекция 2 Техническая реализация многопроцессорных систем
- •Лекция 3 Система передачи сообщений mpi
- •Принципы работы mpich
- •Лекция 4 Структура mpi-программы
- •Int main(int argc, char* argv[]) { int procs_rank, procs_count; // Определяем переменные
- •Int mpi_Init (int* argc, char*** argv)
- •Int mpi_Comm_size(mpi_Comm comm, int *size)
- •Int mpi_Comm_rank(mpi_Comm comm, int *rank)
- •Int mpi_Finalize(void)
- •Определение времени выполнения mpi программы
- •Понятие коммуникатора
- •Лекция 5 Передача сообщений
- •Общие сведения о функциях передачи сообщений
- •Передача сообщения «точка-точка»
- •Int mpi_Send(void *buf, int count, mpi_Datatype type, int dest, int tag, mpi_Comm comm)
- •Прием сообщений «точка-точка» с блокировкой
- •Int mpi_Recv(void *buf, int count, mpi_Datatype type, int source, int tag, mpi_Comm comm, mpi_Status *status)
- •Int main(int argc, char* argv[])
- •Int ProcNum, ProcRank, RecvRank;
- •Лекция 6 Определение времени выполнения программы
- •Int s1; // Место под результат
- •Int size; // Размер принимаемого массива
- •Int Summa; // Сумма его элементов
- •Input n: 1000
- •Лекция 7 Функции неблокирующего обмена данными
- •Int mpi_Test(mpi_Request *request, int *flag,
- •Int mpi_Wait(mpi_Request *request, mpi_status *status)
- •Одновременное выполнение приема и передачи данных
- •Int mpi_Sendrecv (void *sbuf, int scount,
- •Int stag, void *rbuf, int rcount,
- •Int rtag, mpi_Comm comm,
- •Int mpi_Sendrecv_replace (void *buf, int count,
- •Int stag, int source,
- •Int rtag, mpi_Comm comm,
- •Лекция 8 Коллективные операции передачи данных
- •Функция синхронизации процессов
- •Int mpi_Barrier(mpi_Comm comm);
- •Широковещательная рассылка данных
- •Int mpi_Bcast (void* buffer, int count,
- •Int main(int argc, char* argv[])
- •Int proc_rank, proc_count;
- •Широковещательная рассылка индивидуальных данных
- •Int mpi_Scatter
- •Void *rbuf, int rcount, mpi_Datatype rtype,
- •Int root, mpi_Comm comm)
- •Лекция 9 Функции сбора блоков данных от всех процессов группы
- •Int mpi_Gather
- •Void* recvbuf, int recvcount, mpi_Datatype recvtype,
- •Int root, mpi_Comm comm);
- •Int array[100];
- •Int root, *rbuf, proc_count;
- •Int mpi_Allgather
- •Void *rbuf, int rcount, mpi_Datatype rtype,
- •Передача данных от всех процессов всем процессам
- •Int mpi_Alltoall
- •Void *rbuf, int rcount, mpi_Datatype rtype,
- •Лекция 10 Редукция данных
- •Int mpi_Reduce (void *sendbuf, void *recvbuf,
- •Int count, mpi_Datatype type,
Int main(int argc, char* argv[])
{
Int proc_rank, proc_count;
int mas[10];
int i;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &proc_count);
MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
//==========================================================
if (proc_rank==0) // Если это "главный" процесс
{
for (i=0; i<10; i++)
mas[i]=i+1;
}
//==========================================================
// Дальнейший код выполняется всеми процессами
// (в том числе и главным):
MPI_Bcast (mas, 10, MPI_INT, 0, MPI_COMM_WORLD);
for (i=0; i<10; i++)
cout << proc_rank << '_' << mas[i] << " ";
cout << '\n';
MPI_Finalize();
// закрываем MPI-библиотеку
return 0;
}
Как можно видеть, в блок if вынесены действия, свойственные только процессу с рангом 0. Все последующие действия являются одинаковыми для всех процессов. Если после широковещательной рассылки данных необходимо снова разделить действия для разных процессов, после функции MPI_Bcast можно снова использовать операторы if, анализирующие ранг процесса.
Широковещательная рассылка индивидуальных данных
Обобщенная операция распределения данных отличается от широковещательной рассылки тем, что процесс передает процессам различающиеся данные (см. рисунок).
Выполнение данной операции может быть обеспечено при помощи функции:
Int mpi_Scatter
(void *sbuf, int scount, MPI_Datatype stype,
Void *rbuf, int rcount, mpi_Datatype rtype,
Int root, mpi_Comm comm)
где
sbuf, scount, stype – параметры передаваемого сообщения (scount определяет количество элементов, передаваемых каждому процессу);
rbuf, rcount, rtype – параметры для приема своей части рассылаемого сообщения;
root – ранг процесса, выполняющего рассылку данных;
comm – коммуникатор, в рамках которого выполняется передача данных.
При вызове данной функции процесс с рангом root произведет передачу данных всем другим процессам в коммуникаторе. Каждому процессу будет отправлено scount элементов. Процесс с рангом 0 (это не обязательно тот процесс, который делает рассылку данных) получит блок данных из sbuf из элементов с индексами от 0 до scount-1, процессу с рангом 1 будет отправлен блок из элементов с индексами от scount до 2*scount-1 и т.д. Тем самым, общий размер отправляемого сообщения должен быть равен scount*p элементов, где p есть количество процессов в коммуникаторе comm.
Следует отметить, что поскольку функция MPI_Scatter определяет коллективную операцию, вызов этой функции при выполнении рассылки данных должен быть обеспечен в каждом процессе коммуникатора.
Отметим также, что функция MPI_Scatter передает всем процессам сообщения одинакового размера. Выполнение более общего варианта операции распределения данных, когда размеры сообщений для процессов могут быть разного размера, обеспечивается при помощи функции MPI_Scatterv. Студентам предлагается самостоятельно изучить данную функцию по документации к библиотеке MPI и материалам в сети Интернет.
