Академический Документы
Профессиональный Документы
Культура Документы
MPI_[I][R,S,B]Send();
При этом в языке С только первый символ после префикса MPI_ записывается с помощью
символа верхнего регистра, например MPI_Irsend(). Символы в квадратных скобках обо-
значают:
Функции передачи и приема без этих символов, называются стандартными функциями пере-
дачи и приема.
2
a) б)
Рис.6.1 – Блокирующий (а) и неблокирующий (б) обмены сообщениями
Таким образом, библиотека MPI предоставляет обширный "полигон" возможностей ор-
ганизации обмена между процессами, но их необходимо исследовать для каждой задачи, с
целью получить максимальную эффективность по быстродействию, надежности и исполь-
зуемой памяти. Для обеспечения всевозможных режимов в библиотеке имеются различные
дополнительные функции, которые лишь кратко перечислим.
Функции управления дополнительным буфером для буферизованного обмена:
где параметр flag устанавливается в единицу, если операция, request заданная идентифи-
катором операции обмена, выполнена.
Имеется функция совместного приема-передачи:
Функция должна быть вызвана во всех процессах, в которых необходимо принять дан-
ные. Схематично эту операцию можно изобразить следующим рисунком (рис. 6.2)
#include "mpi.h"
#include <stdio.h>
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&P);
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
if(myrank==0)
{
puts("Enter size of array");
scanf("%d",&n);
x=(float *)malloc(n*sizeof(float));
if(x==NULL) MPI_Abort(MPI_COMM_WORLD,err);
for(i=0;i<n;i++)
x[i]=(float)i;//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
M=n/P;
}
MPI_Bcast(&M,1,MPI_INT,0,MPI_COMM_WORLD);
if(myrank!=0)
{
x=(float *)malloc(M*sizeof(float));
if(x==NULL) MPI_Abort(MPI_COMM_WORLD,err);
}
y=(float *)calloc(M,sizeof(float));
if(y==NULL) MPI_Abort(MPI_COMM_WORLD,err);
MPI_Scatter(x,M,MPI_FLOAT,x,M,MPI_FLOAT,0,MPI_COMM_WORLD);
for(i=0;i<M;i++)
sum+=x[i];
MPI_Barrier(MPI_COMM_WORLD);
MPI_Reduce(&sum,&total,1,MPI_FLOAT,MPI_SUM,0,MPI_COMM_WORLD);
MPI_Reduce(x,y,M,MPI_FLOAT,MPI_SUM,0,MPI_COMM_WORLD);
if(myrank==0)
{
printf("Reduce total=%.0f\n",total); //Reduce 120
printf("Reduce: ");
for(i=0;i<M;i++)
printf("y[%d]=%.0f ",i,y[i]); //Reduce 24 28 32 36
printf("\n");
}
MPI_Gather(&sum,1,MPI_FLOAT,y,1,MPI_FLOAT,0,MPI_COMM_WORLD);
Высокопроизводительные вычислительные системы и параллельное программирование. Кудерметов Р.К.
7
if(myrank==0)
{
printf("Gather: ");
for(i=0;i<M;i++)
printf("y[%d]=%.0f ",i,y[i]); //Gather 6 22 38 54
printf("\n");
}
MPI_Scan(x,y,M,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD);
for(i=0;i<P;i++)
if(myrank==i)
{
printf("Scan:\n");
printf("#%d: ",myrank);
for(j=0;j<M;j++)
printf("y[%d]=%.0f ",j,y[j]);// Scan #0 0 1 2 3
printf("\n"); // #1 4 6 8 10
} // #2 12 15 18 21
free(y); // #3 24 28 32 36
free(x);
MPI_Finalize();
return 0;
}