Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MPI - MKM.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
391.79 Кб
Скачать

92 Сурак

1. Можно ли запустить программу SIMD на современных процессорах семейства x86.

x86 — архитектура процессора c одноимённым набором команд, впервые реализованная в процессорах компании Intel.Название образовано от двух цифр, которыми заканчивались названия процессоров Intel ранних моделей:  8086, 80186, 80286 (i286), 80386 (i386),80486 (i486). За время своего существования набор команд постоянно расширялся, сохраняя совместимость с предыдущими поколениями.

Для организации групповой обработки данных в процессорах используется SIMD расширения к х86 инструкциям. Аббревиатура SIMD расшифровывается как Single Instruction Multiple Data (одна инструкция – множество данных). Под SIMD расширением понимается программно-аппартное решение, представляющее собой совокупность дополнительных регистров и наборов инструкций процессора, предназначенных для групповой обработки данных. Также необходимо наличие соответствующих компиляторов, ”знающих” SIMD инструкции и способных оптимизировать под них код. Быстродействие повышается за счет того, что каждая команда из дополнительного набора выполняет действие, для которого понадобилось бы несколько команд основного набора. Оптимизированная программа, как правило, может работать на процессорах как с поддержкой необходимых инструкций (повышенное быстродействие), так и с отсутствием оных. Однако на практике встречаются программы, которые отказываются работать при отсутствии у процессора определенного набора SIMD инструкций. Такая проблема может возникнуть на старых процессорах, при использовании современных программ.

Однако такие исключения встречаются редко и в большинстве случаeв программа, взамен отсутствующих SIMD, будет использовать универсальные (generic) х86 инструкции. При этом мы не получим никакого повышения быстродействия, но и снижения производительности (по сравнению с обычным кодом) также не будет. 

2. Пользовательские типы данных. Тип MPI_type_indexed (hindexed). Примеры.

MPI разрешает пользователю во время выполнения создавать собственные типы данных MPI. Чтобы построить тип данных для MPI, необходимо определить расположение данных в типе: тип элементов и их относительные местоположения в памяти. Такой тип называют производным типом данных.

Конструктор типа MPI_Type_indexed является универсальным конструктором, так как элементы создаваемого типа состоят из произвольных по длине блоков с произвольным смещением блоков от начала размещения элемента. Смещения измеряются в элементах старого типа.

int MPI_Type_indexed(int count, int *array_of_blocklengths, int *array_of_displacements, MPI_Datatype

oldtype, MPI_Datatype *newtype)

count – числоблоков; array_of_blocklengths – массив, содержащийчислоэлементовбазовоготипавкаждомблоке; array_of_displacements – массивсмещенийкаждогоблокаотначаларазмещенияэлементановоготипа, смещенияизмеряютсячисломэлементовбазовоготипа; oldtype – базовыйтипданных; newtype – новыйпроизводныйтипданных.

Этафункциясоздаеттип newtype, каждыйэлементкоторогосостоитиз count блоков, где i-ыйблоксодержит array_of_blocklengths[i] элементовбазовоготипаисмещенотначаларазмещенияэлементановоготипана array_of_displacements[i] элементовбазовоготипа.

Конструктор типа MPI_Type_hindexed идентичен конструктору MPI_Type_indexed за исключением того, что смещения измеряются в байтах.

int MPI_Type_hindexed(int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements, MPI_Datatype oldtype, MPI_Datatype *newtype)

3. Решение 2-мерного уравнения Лапласа методом 1-мерной декомпозиции.

constint N=100;

float P[N][N],

h=0.01, //шаг сетки

eps=0.01, //точность

max, //норма

**p, //текущая итерация

**pp, //предыдущая итерация

a[N],b[N]; //вспомогательные векторы

inti,j,

c, //кол-во строк матрицы на каждом процессоре

stop = 1; //условие заверщения цикла

intrank,size;

MPI_Init(&argc,&argv);

MPI_Status status;

MPI_Comm_rank(MPI_COMM_WORLD,&rank);

MPI_Comm_size(MPI_COMM_WORLD,&size);

if(rank<N%size)

{

c=N/size+1;

}else

{

c=N/size;

}

p=newfloat*[c];

pp=newfloat*[c];

for(i=0;i<c;i++)

{

p[i]=newfloat[N];

pp[i]=newfloat[N];

p[i][0]=1;

pp[i][0]=1;

for(int j=1;j<N;j++)

{

p[i][j]=0;

pp[i][j]=0;

}

}

if(rank==0)

{

do

{

if(size>1)

{

MPI_Send(&p[c-1][0],N,MPI_FLOAT,rank+1,

0,MPI_COMM_WORLD);

MPI_Recv(a,N,MPI_FLOAT,rank+1,size,

MPI_COMM_WORLD, &status);

}

max=0.0;

for(i=1;i<c-1;i++)

{

for(j=1;j<N-1;j++)

{

p[i][j]=(pp[i+1][j]+pp[i-1][j]+pp[i][j+1]+pp[i][j-1])/4;

if(max<fabs(p[i][j]-pp[i][j]))

{

max=fabs(p[i][j]-pp[i][j]);

}

}

}

if(size>1)

{

for(j=1;j<N-1;j++)

{

p[c-1][j]=(pp[c-2][j]+a[j]+pp[c-1][j+1]+pp[c-1][j-1])/4;

if(max<fabs(p[c-1][j]-pp[c-1][j]))

{

max=fabs(p[c-1][j]-pp[c-1][j]);

}

}

floatmaxx;

for(i=1;i<size;i++)

{

MPI_Recv(&maxx,1,MPI_FLOAT,i,2*size,MPI_COMM_WORLD,&status);

if(maxx>max)

{

max=maxx;

}

}

}

if(max<=eps)

{

stop=0;

}

if(size>1)

{

for(i=1;i<size;i++)

{

MPI_Send(&stop,1,MPI_INT,i,3*size,MPI_COMM_WORLD);

}

}

for(i=0;i<c;i++)

{

for(j=0;j<N;j++)

{

pp[i][j]=p[i][j];

}

}

}while(stop==1);

for(i=0;i<c;i++)

{

for(int j=0;j<N;j++)

{

P[i][j]=p[i][j];

}

}

if(size>1)

{

intjj=c-1;

for(i=1;i<size;i++)

{

MPI_Recv(&c,1,MPI_INT,i,4*size,MPI_COMM_WORLD,&status);

for(j=0;j<c;j++)

{

jj++;

MPI_Recv(&P[jj][0],100,MPI_FLOAT,i,5*size,MPI_COMM_WORLD,&status);

}

}

}

ofstream out("result.txt");

for(i=0;i<N;i++)

{

for(int j=0;j<N;j++)

{

out<<P[i][j]<<'\t'; //вывожу в результаты в фаил

}

out<<'\n';

}

}

if(rank==size-1&&size>1)

{

do

{

MPI_Recv(b,N,MPI_FLOAT,rank-1,0,MPI_COMM_WORLD,&status);

MPI_Send(&p[0][0],N,MPI_FLOAT,rank-1,size,MPI_COMM_WORLD);

max=0;

for(i=1;i<c-1;i++)

{

for(j=1;j<N-1;j++)

{

p[i][j]=(pp[i+1][j]+pp[i-1][j]+pp[i][j+1]+pp[i][j-1])/4;

if(max<fabs(pp[i][j]-p[i][j]))

{

max=fabs(pp[i][j]-p[i][j]);

}

}

}

for(j=1;j<N-1;j++)

{

p[0][j]=(pp[1][j]+b[j]+pp[0][j+1]+pp[0][j-1])/4;

if(max<fabs(pp[0][j]-p[0][j]))

{

max=fabs(pp[0][j]-p[0][j]);

}

}

MPI_Send(&max,1,MPI_FLOAT,0,2*size,MPI_COMM_WORLD);

for(i=0;i<c;i++)

{

for(j=0;j<N;j++)

{

pp[i][j]=p[i][j];

}

}

MPI_Recv(&stop,1,MPI_INT,0,3*size,MPI_COMM_WORLD,&status);

}while(stop==1);

MPI_Send(&c,1,MPI_INT,0,4*size,MPI_COMM_WORLD);

for(i=0;i<c;i++)

{

MPI_Send(&p[i][0],N,MPI_FLOAT,0,5*size,MPI_COMM_WORLD);

}

}

if(rank>0&&rank<size-1)

{

do

{

MPI_Recv(b,N,MPI_FLOAT,rank-1,0,MPI_COMM_WORLD,&status);

MPI_Send(&p[c-1][0],N,MPI_FLOAT,rank+1,0,MPI_COMM_WORLD);

MPI_Recv(a,N,MPI_FLOAT,rank+1,size,MPI_COMM_WORLD,&status);

MPI_Send(&p[0][0],N,MPI_FLOAT,rank-1,size,MPI_COMM_WORLD);

max=0;

int ii;

if(rank<N%size||100%size==0)

{

ii=rank*c;

}

if(rank>N%size&&100%size!=0)

{

ii=(N%size)*(c+1)+(rank-N%size)*c;

}

for(i=1;i<c-1;i++)

{

for(j=1;j<N-1;j++)

{

p[i][j]=(pp[i+1][j]+pp[i-1][j]+pp[i][j+1]+pp[i][j-1])/4;

if(max<fabs(pp[i][j]-p[i][j]))

{

max=fabs(pp[i][j]-p[i][j]);

}

}

}

for(j=1;j<N-1;j++)

{

p[0][j]=(pp[1][j]+b[j]+pp[0][j+1]+pp[0][j-1])/4;

if(max<fabs(pp[0][j]-p[0][j]))

{

max=fabs(pp[0][j]-p[0][j]);

}

p[c-1][j]=(pp[c-2][j]+a[j]+pp[c-1][j+1]+pp[c-1][j-1])/4;

if(max<fabs(pp[c-1][j]-p[c-1][j]))

{

max=fabs(pp[c-1][j]-p[c-1][j]);

}

}

MPI_Send(&max,1,MPI_FLOAT,0,2*size,MPI_COMM_WORLD);

for(i=0;i<c;i++)

{

for(j=0;j<N;j++)

{

pp[i][j]=p[i][j];

}

}

MPI_Recv(&stop,1,MPI_INT,0,3*size,MPI_COMM_WORLD,&status);

}while(stop==1);

MPI_Send(&c,1,MPI_INT,0,4*size,MPI_COMM_WORLD);

for(i=0;i<c;i++)

{

MPI_Send(&p[i][0],N,MPI_FLOAT,0,5*size,MPI_COMM_WORLD);

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]