на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Паралельні обчислення з використанням MPI
p align="left">rcvtype - тип прийнятих даних;

root - ранг передавального процесу;

comm - комунікатор.

Вихідний параметр rcvbuf - адреса буфера прийому. Працює ця підпрограма в такий спосіб. Процес з рангом root ("головний процес") розподіляє вміст буфера передачі sendbuf серед усіх процесів. Уміст буфера передачі розбивається на кілька фрагментів, кожний з який містить sendcount елементів. Перший фрагмент передається процесу 0, другий процесу 1 і т.д. Аргументи send мають значення тільки на стороні процесу root.

При зборці (MPI_Gather) кожен процес у комунікаторі comm пересилає вміст буфера передачі sendbuf процесу з рангом root. Процес root "склеює" отримані дані в буфері прийому. Порядок склейки визначається рангами процесів, тобто в результуючому наборі після даних від процесу 0 випливають дані від процесу 1, потім дані від процесу 2 і т.д. Аргументи rcvbuf, rcvcount і rcvtype відіграють роль тільки на стороні головного процесу. Аргумент rcvcount указує кількість елементів даних, отриманих від кожного процесу (але не їхня сумарна кількість). При виклику підпрограм MPI_scatter і MPI_Gather з різних процесів варто використовувати загальний головний процес.

Операції приведення і сканування

Операції приведення і сканування відносяться до категорії глобальних обчислень. У глобальній операції приведення до даних від усіх процесів із заданого комунікатора застосовується операція MPI_Reduce (див рис).

Аргументом операції приведення є масив даних -- по одному елементі від кожного процесу. Результат такої операції -- єдине значення (тому вона і називається операцією приведення).

У підпрограмах глобальних обчислень функція, передана в підпрограму, може бути: визначеною функцією MPI, наприклад MPI_SUM, користувальницькою функцією, а також оброблювачем для користувальницької функції, що створюється підпрограмою MPI_Op_create.

Три версії операції приведення повертають результат:

одному процесу;

усім процесам;

розподіляють вектор результатів між усіма процесами.

Операція приведення, результат якої передається одному процесу, виконується при виклику підпрограми MPI_Reduce:

int MPI_Reduce(void *buf, void *result, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

Вхідні параметри підпрограми MPI_Reduce:

buf -- адреса буфера передачі;

count -- кількість елементів у буфері передачі;

datatype -- тип даних у буфері передачі;

ор -- операція приведення;

root -- ранг головного процесу;

comm -- комунікатор.

Підпрограма MPI_Reduce застосовує операцію приведення до операндам з buf, а результат кожної операції міститься в буфер результату result. MPI_Reduce повинна викликатися всіма процесами в комунікаторі comm, a аргументи count, datatype і op у цих викликах повинні збігатися. Функція приведення (ор) не повертає код помилки, тому при виникненні аварійної ситуації або завершується робота всієї програми, або помилка мовчазно ігнорується. І те й інше в однаковій мірі небажано.

У MPI мається 12 визначених операцій приведення (див. табл.).

Операція

Опис

MPI_MAX

Визначення максимальних значень елементів одномірних масивів цілого чи речовинного типу

MPI_MIN

Визначення мінімальних значень елементів одномірних масивів цілого чи речовинного типу

MPI_SUM

Обчислення суми елементів одномірних масивів цілого, речовинного чи комплексного типу

MPI_PROD

Обчислення заелементного добутку одномірних масивів цілого, речовинного чи комплексного типу

MPI_LAND

Логічне "И"

MPI_BAND

Бітове "И"

MPI_LOR

Логічне "ЧИ"

MPI_BOR

Бітове "ЧИ"

MPI_LXOR

Логічне "ЧИ", що виключає

MPI_BXOR

Бітове "ЧИ", що виключає

MPI_MAXLOC

Максимальні значення елементів одномірних масивів і їхні індекси

MPI_MINLOC

Мінімальні значення елементів одномірних масивів і їхні індекси

Розглянемо приклад 3:

===== Example2.cpp =====

#include <mpi.h>

#include <stdio.h>

#include <math.h>

int main(int argc, char *argv[])

{

int n, myid, numprocs, i;

double PI25DT = 3.141592653589793238462643;

double mypi, pi, h, sum, x;

MPI_Init(&argc,&argv);

MPI_Comm_size(MPI_COMM_WORLD,&numprocs);

MPI_Comm_rank(MPI_COMM_WORLD,&myid);

while (1) {

if (myid == 0) {

printf("Enter the number of intervals: (0 quits) ");

scanf("%d",&n);

}

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

if (n == 0)

break;

else {

h = 1.0 / (double) n;

sum = 0.0;

for (i = myid + 1; i <= n; i += numprocs) { //розподіл навантаження

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

sum += (4.0 / (1.0 + x*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));

}

MPI_Finalize();

return 0;

}

===== Example2.cpp =====

Ця програма обчислює число р методом підсумовування ряду. Спочатку один із процесів (0) запитує число інтервалів, що потім поширює іншим процедурою MPI_Bcast. Помітьте, що процедура MPI_Bcast для процесу 0 є передавальної, а для всіх інших - приймаючої. Кінцеві результати обчислень здаються процесу 0 для підсумовування: процедура

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

збирає з усіх процесів перемінну mypi, підсумовує (MPI_SUM), і зберігає результат у змінної pi процесу 0.

Вивід приклада: Example3 output (np = 6)

Process 5 on apc-pc.

Process 3 on apc-pc.

Process 0 on apc-pc.

Enter the number of intervals: (0 quits) Process 1 on apc-pc.

Process 2 on apc-pc.

Process 4 on apc-pc.

15

pi is approximately 3.1419630237914191, Error is 0.0003703702016260

wall clock time = 0.031237

Enter the number of intervals: (0 quits) 2

pi is approximately 3.1623529411764704, Error is 0.0207602875866773

wall clock time = 0.000943

Enter the number of intervals: (0 quits) 0

Завдання 1: поясніть вивід;)

Приклад 4 показує створення комплексної системи керування процесами на прикладі розподіленого дешифратора паролів. Використовується структура master-slave (головн-підлеглий).

===== Example4.cpp =====

#include <mpi.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define TAG_READY 99

#define TAG_RESULT 98

int do_decrypt_pass(char* incoming_pass_str, char * result_pass_str, int length)

{

if (length % 2 == 0) return 1;

else return 0;

}

int main(int argc, char* argv[])

{

int k,x;

char in_line[256],acc_name[256],acc_pass[256];

int myrank, size;

MPI_Status status;

MPI_Init(&argc,&argv);

MPI_Comm_size(MPI_COMM_WORLD,&size);

MPI_Comm_rank(MPI_COMM_WORLD,&myrank);

if (myrank == 0) // kind'a Master Process

{

puts("Initializing"); fflush(stdout);

FILE* in_file = fopen("pass.txt","r");

for (x=1;x<size;x++) MPI_Recv (&k, 1, MPI_INT, x, TAG_READY, MPI_COMM_WORLD, &status);

char* p;

puts ("Feeding"); fflush(stdout);

sprintf(in_line,"apc::1234");

if (p = strtok(in_line,"::")) sprintf(acc_name,"%s",p); else return 0;

if (p = strtok(NULL,"::")) sprintf(acc_pass,"%s",p); else return 0;

int acc_name_len = strlen(acc_name)+1, acc_pass_len = strlen(acc_pass)+1;

MPI_Bcast(&acc_name_len, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast(&acc_pass_len, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast(&acc_name, acc_name_len, MPI_CHAR, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast(&acc_pass, acc_pass_len, MPI_CHAR, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

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

{

MPI_Probe(MPI_ANY_SOURCE, TAG_RESULT, MPI_COMM_WORLD, &status);

int src = status.MPI_SOURCE; int res;

MPI_Recv(&res, 1, MPI_INT, src, TAG_RESULT, MPI_COMM_WORLD, &status);

printf("Proc %d returned %d\n",src,res);fflush(stdout);

}

}

else

{

MPI_Ssend(&myrank, 1, MPI_INT, 0, TAG_READY, MPI_COMM_WORLD);

int acc_name_len, acc_pass_len;

MPI_Bcast(&acc_name_len, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast(&acc_pass_len, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast(&acc_name, acc_name_len, MPI_CHAR, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast(&acc_pass, acc_pass_len, MPI_CHAR, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);

printf("Proc %d: recv %s:: %s\n",myrank,acc_name,acc_pass);fflush(stdout);

char[256] ret_pass;

int result = do_decrypt_pass(&acc_pass, &ret_pass, myrank);

MPI_Ssend(&result, 1, MPI_INT, 0, TAG_RESULT, MPI_COMM_WORLD);

}

MPI_Finalize();

return 0;

}

===== Example4.cpp =====

У цьому прикладі головний процес (ранг 0) чекає підключення всіх підлеглих процесів (посилки ними повідомлення з тегом TAG_READY), розсилає рядок in_line усім підлеглим процесам, що намагаються підібрати пароль довжини myrank (тобто власний номер процесу). Власне зломом займається функція int do_decrypt_pass(char* incoming_pass_str, char * result_pass_str, int length)

Процеси повертають результат підбора c повідомленням TAG_RESULT. MPI_Barrier використовується для синхронізації. Висновок приклада:

Example4 output (np = 5)

Initializing

Feeding

Proc 1: recv apc:: 1234

Proc 2: recv apc:: 1234

Proc 3: recv apc:: 1234

Proc 1 returned 0

Proc 4: recv apc:: 1234

Proc 3 returned 0

Proc 2 returned 1

Proc 4 returned 1

У цьому прикладі всі процеси ламають той самий пароль, і новий цикл (не реалізований у прикладі) не почнеться, поки не завершать роботу всі процеси. Отже, час одного циклу визначається часом роботи процесу з максимальним рангом (тобто виконуючого підбор найбільшої довжини => перебір найбільшого числа комбінацій).

Приклад 5 показує більш зроблену систему, що читає з необхідну інформацію з файлу, і роздає кожному процесу по паролі. Процеси працюють в асинхронному режимі, зв'язуючи з головним процесом, що відіграє роль «роздавального-прийомного центра», організовуючи систему дуже схожу на «клієнта-сервер».

Завдання 2: Після вивчення коду поясніть, чому це не є системою клієнт-сервер.

===== Example5.cpp =====

#include <mpi.h>

Страницы: 1, 2, 3, 4



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.