
- •5. Коллективные операции передачи данных. Основные определения. Принцип взаимодействия процессов при выполнении барьерной синхронизации, широковещательной передачи, операций сборки и рассылки данных.
- •1. Барьерная синхронизация mpi_Barrier (mpi_Comm comm)
- •2. Широковещательная передача mpi_bcast
- •6. Принцип взаимодействия параллельных процессов при выполнении обобщенных коллективных операций сборки и рассылки данных.
- •7. Типы данных mpi. Понятие производных типов данных mpi. Конструкторы производных типов данных.
- •8. Управление группами процессов и коммуникаторами. Конструирование групп и коммуникаторов.
- •10. Технология программирования OpenMp. Основные конструкции OpenMp с реализации.
6. Принцип взаимодействия параллельных процессов при выполнении обобщенных коллективных операций сборки и рассылки данных.
Под коллективными операциями в MPI понимаются операции над данными, в которых принимают участие все процессы в группе, определяемой одним коммуникатором. В противном случае, происходит ошибка, и выполнение параллельной программы прекращается. Коммуникатор обеспечивает контекст коллективных операций в группе.
Вызов коллективной функции на процессе возвращает управление сразу после того, как только его участие в коллективной операции завершено. Завершение вызова не означает, что другие процессы в группе завершили коллективную операцию, а только показывает, что процесс-отправитель может обращаться к буферу обмена. Таким образом, вызов коллективной операции имеет эффект синхронизации всех процессов в группе.
Используемые в коллективных операциях типы данных, должны совпадать у процесса-отправителя и процесса получателя. Условия соответствия типов для коллективных операций более строгие, чем аналогичные условия для парного обмена. А именно для коллективных операций количество посланных данных должно точно соответствовать количеству данных, описанных в процессе-получателе. Коллективные операции могут иметь один процесс-отправитель или получатель или отправителями/получателями являются все процессы в группе. Различные коллективные операции (широковещание, сбор данных) имеют единственный процесс-отправитель или процесс-получатель. Такой процесс называются корневым (root).
Некоторые аргументы в коллективных функциях определены как “существенные только для корневого процесса” и игнорируются для всех других участников операции.
Вызовы коллективных операций могут использовать те же коммуникаторы, что и парный обмен, при этом MPI гарантирует, что сообщения, созданные коллективными операциями, не будут смешаны с сообщениями, созданными парным обменом. Ключевым понятием в коллективных функциях является группа участвующих процессов, но в качестве явного аргумента выступает коммуникатор. Коммуникатор понимается как идентификатор группы, связанный с контекстом. Не разрешается использовать в качестве аргумента коллективной функции интер-коммуникатор (коммуникатор, для выполнения парных обменов между группами различных коммуникационных пространств).
К обобщенным коллективным операциям сборки и рассылки данных относятся функции MPI_Scatterv(…), MPI_Gatherv(…), MPI_Allgather(…),MPI_Alltoall(…).
В отличие от MPI_Gather при использовании функции MPI_Gatherv разрешается принимать от каждого процесса данные разной длины, поэтому в функции MPI_Gatherv аргумент recvcounts, является массивом, каждый элемент которого определяет количество принимаемых данных от каждого процесса.
Выполнение MPI_Gatherv будет давать такой же результат, как если бы каждый процесс, включая корневой, посылал корневому процессу сообщение: MPI_Send(sendbuf, sendcount, sendtype, root, …), а принимающий процесс выполнил p операций приема: MPI_Recv(recvbuf+displs[i]*extern(recvtype), recvcounts[i], recvtype, i, …), где extent(recvtype) это протяжённость типа (количество байт), получаемая с помощью вызова MPI_Type_extent(), где i изменяется от 0 до p, p - количество процессов в группе.
Сообщения помещаются в буфер принимающего процесса в порядке возрастания номеров процессов, то есть данные, посланные процессом i, помещаются в i-ю часть принимающего буфера recvbuf на корневом процессе. i-я часть recvbuf начинается со смещения displs[i]. В принимающем процессе значимыми являются все аргументы функции MPI_Gatherv, на остальных процессах только аргументы передачи: sendbuf, sendcount, sendtype, root, comm. Переменные comm и root должны иметь одинаковые значения во всех процессах.
Обобщенная операция рассылки является противоположной операцией сборки. MPI_Scatterv функционально расширяет MPI_Scatter, допуская распределение данных разной длины для каждого процесса, обладает большей гибкостью при выборке передаваемых данных из корневого процесса, позволяя выбирать для распределения данные с разрывным расположением в памяти. Обязательным условием корректной работы обобщенной рассылки является соблюдение равенства между количеством передаваемых данных из корневого процесса и количеством получаемых данных на соответствующем принимающем процессе.
MPI_Allgather можно рассматривать, как выполнение каждым процессом операции MPI_Gather, где каждый, процесс получает результат (каждый процесс есть root). При выполнении MPI_Allgather блок данных, переданный j-ым процессом, принимается каждым процессом в j-ый блок буфера recvbuf.
MPI_Alltoall является расширением MPI_Allgather на случай, когда каждый процесс посылает блок данных каждому процессу, по следующему правилу: j-ый блок, посылаемый процессом i, будет получен процессом j и помещён в i-ый блок буфера recvbuf. Значения sendcount, sendtype в каждом процессе должны быть одинаковыми. Т.е. количество посланных данных должно быть равно количеству полученных данных между каждой парой процессов. Результат выполнения операции эквивалентен тому, как если бы каждый процесс передал сообщение каждому процессу (включая себя), вызвав
MPI_Send(sendbuf + isendcountextent(sendtype), sendcount, sendtype, i, ...), и принял сообщение от каждого процесса, вызвав
MPI_Recv(recvbuf + irecvcountextent(recvtype), recvcount, recvtype, i, ...).