Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пояснительная записка Гуцу Олег.docx
Скачиваний:
5
Добавлен:
21.09.2019
Размер:
2.32 Mб
Скачать

Настройка mpich2

Необходимо со­здать на каждом ком­пью­те­ре поль­зо­ва­те­ля с одина­ко­вым име­нем и па­ро­лем. От име­ни это­го поль­зо­ва­те­ля бу­дут за­пускать­ся MPI-про­грам­мы.

Лю­бое дей­ствие си­сте­ма MPICH вы­пол­ня­ет от ука­зан­но­го име­ни пользо­ва­те­ля. Для то­го, что­бы спра­ши­вать имя поль­зо­ва­те­ля и па­роль, исполь­зу­ет­ся про­грам­ма Wmpiregister. Про­бле­ма в том, что имя поль­зо­ва­те­ля и па­роль спра­ши­ва­ют­ся до­ста­точ­но ча­сто, что мо­жет вы­зы­вать раз­дра­же­ние. Для то­го, что­бы это­го из­бе­жать, Wmpiregister мо­жет со­хра­нять имя пользовате­ля и па­роль в ре­ест­ре Windows. Для этого необходимо:

  • запустить программу wmpiregister,

  • ввести имя пользователя в поле Account,

  • ввести пароль в поле password,

  • нажать кнопку Register

  • нажать кнопку OK

Теперь при обращении к mpiexec, задания будут выполняться на всех узлах от имени этого пользователя, и вводить пароль повторно пользователю mpich2 не придётся.

Рис. 2.8. Скриншот программы wmpiregister

Создание общего сетевого ресурса

Для удоб­но­го за­пус­ка MPI-про­грамм сле­ду­ет со­здать на од­ном из ком­пью­те­ров об­щий се­те­вой ре­сурс. Для этого требуется в свойствах папки на вкладке «Доступ» (в нерусифицированной версии Windows – «Sharing») открыть доступ к папке. В этой папке будут храниться MPI-программы и выходные данные тестирующих программ.

        1. Описание хода лабораторной работы №1 Со­зда­ние mpi-про­грам­мы в Visual Studio

Необходимо добавить файлы библиотеки MPICH2 в среду разработки.(Рис. 2.9, 2.10)

Рис. 2.9. Добавление заголовочных файлов mpich2 в среду разработки Visual C++.

Рис. 2.10. Добавление библиотечных файлов mpich2 в среду разработки Visual C++.

Также необходимо добавить библиотеку mpi.lib в проект, отредактировав свойства проекта (Рис. 2.11).

Рис. 2.11. Добавление библиотеки mpi.lib в проект Visual C++.

Любой участок кода, который может быть выполнен отдельно независимо от других, можно выполнять параллельно в отдельном потоке или процессе. Для демонстрации воспользуемся программой вычисляющей число Пи. Метод нахождения числа Пи заключается в численном решении интеграла:

Вычисление такого интеграла по методу прямоугольников сводится к дискретизации подынтегральной функции и суммированию площадей прямоугольников под функцией (Рис. 2.12):

Рисунок 2.12. Подынтегральная функция.

Чем выше частота дискретизации, тем точнее результат.

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

Программа при запуске запрашивает у пользователя в интерактивном режиме число интервалов для суммирования – это и есть частота дискретизации(n).

Листинг программы mpi-программы

// Подключение необходимых заголовков

#include <stdio.h>

#include <math.h>

// Подключение заголовочного файла MPI

#include "mpi.h"

// Функция для промежуточных вычислений

double f(double a)

{

return (4.0 / (1.0+ a*a));

}

// Главная функция программы

int main(int argc, char **argv)

{

// Объявление переменных

int done = 0, n, myid, numprocs, i;

double PI25DT = 3.141592653589793238462643;

double mypi, pi, h, sum, x;

double startwtime = 0.0, endwtime;

int namelen;

char processor_name[MPI_MAX_PROCESSOR_NAME];

// Инициализация подсистемы MPI

MPI_Init(&argc, &argv);

// Получить размер коммуникатора MPI_COMM_WORLD

// (общее число процессов в рамках задачи)

MPI_Comm_size(MPI_COMM_WORLD,&numprocs);

// Получить номер текущего процесса в рамках

// коммуникатора MPI_COMM_WORLD

MPI_Comm_rank(MPI_COMM_WORLD,&myid);

MPI_Get_processor_name(processor_name,&namelen);

// Вывод номера потока в общем пуле

fprintf(stdout, "Process %d of %d is on %s\n", myid,numprocs,processor_name);

fflush(stdout);

while(!done)

{

// количество интервалов

if(myid==0)

{

fprintf(stdout, "Enter the number of intervals: (0 quits) ");

fflush(stdout);

if(scanf("%d",&n) != 1)

{

fprintf(stdout, "No number entered; quitting\n");

n = 0;

}

startwtime = MPI_Wtime();

}

// Рассылка количества интервалов всем процессам (в том числе и себе)

MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

if(n==0)

done = 1;

else

{

h = 1.0 / (double) n;

sum = 0.0;

// Обсчитывание точки, закрепленной за процессом

for(i = myid + 1 ; (i <= n) ; i += numprocs)

{

x = h * ((double)i - 0.5);

sum += f(x);

}

mypi = h * sum;

// Сброс результатов со всех процессов и сложение

MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

// Если это главный процесс, вывод полученного результата

if(myid==0)

{

printf("PI is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT));

endwtime = MPI_Wtime();

printf("wall clock time = %f\n", endwtime-startwtime);

fflush(stdout);

}

}

}

// Освобождение подсистемы MPI

MPI_Finalize();

return 0;

}