Паралельні обчислення з використанням MPI
Контрольная работа - Компьютеры, программирование
Другие контрольные работы по предмету Компьютеры, программирование
printf(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
#include
#include
#include
//типи повідомлень
#define TAG_MSG 98// службове повідомлення зміст перемінної код (див. нижче)
#define TAG_SEND_NAMELEN 97// пересилається довжина рядка імені
#define TAG_SEND_PASSLEN 96// пересилається довжина рядка пароля
#define TAG_SEND_NAME 95// пересилається рядок імені
#define TAG_SEND_PASS 94// пересилається рядок імені
#define MSG_FAILURE 0// невдача при розшифровці
#define MSG_SUCCESS 1// успіх при розшифровці
#define MSG_READY 2// клієнт готовий до прийому наступного пароля
#define MSG_GO_ON 3// сигнал клієнту продовжувати роботу
#define MSG_BREAK 5// сигнал клієнту завершити роботу
int do_decrypt_pass(int param);
int main(int argc, char* argv[])
{
int x,result;
char in_line[256],acc_name[256],acc_pass[256],racc_name[256],racc_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) // kinda Master Process
{
puts("Initializing"); fflush(stdout);
FILE* in_file = fopen("pass.txt","r");
char* p;
int allok=1,numclients=size-1;
int acc_name_len,acc_pass_len,racc_name_len,racc_pass_len;
while (allok || numclients)
{
MPI_Probe(MPI_ANY_SOURCE, TAG_MSG, MPI_COMM_WORLD, &status);// модель подій!
int src = status.MPI_SOURCE;
MPI_Recv(&result, 1, MPI_INT, src, TAG_MSG, MPI_COMM_WORLD, &status);// Чекаємо повідомлень від клієнтів
printf("<<< Proc %d returned %d\n",src,result);fflush(stdout);
switch(result)
{
case MSG_SUCCESS:
MPI_Recv(&racc_name_len, 1, MPI_INT, src,TAG_SEND_NAMELEN, MPI_COMM_WORLD, &status);
MPI_Recv(&racc_pass_len, 1, MPI_INT, src,TAG_SEND_PASSLEN, MPI_COMM_WORLD, &status);
MPI_Recv(&racc_name, racc_name_len, MPI_CHAR, src, TAG_SEND_NAME, MPI_COMM_WORLD, &status);
MPI_Recv(&racc_pass, racc_pass_len, MPI_CHAR, src, TAG_SEND_PASS, MPI_COMM_WORLD, &status);
printf ("[+] Proc %d got: %s:: %s\n",src,racc_name,racc_pass);fflush(stdout);
break;
case MSG_FAILURE:
MPI_Recv(&racc_name_len, 1, MPI_INT, src, TAG_SEND_NAMELEN, MPI_COMM_WORLD, &status);
MPI_Recv(&racc_name, racc_name_len, MPI_CHAR, src, TAG_SEND_NAME, MPI_COMM_WORLD, &status);
printf ("[-] Proc %d couldnt break: %s in set limits\n",src,racc_name);fflush(stdout);
break;
case MSG_READY:// є вільний робітник
if (!fgets(in_line,256,in_file)) allok =0;// готуємо account info
if (p = strtok(in_line,"::")) sprintf(acc_name,"%s",p); else allok= 0;//
if (p = strtok(NULL,"::")) sprintf(acc_pass,"%s",p); else allok= 0;//
if (allok) x = MSG_GO_ON; else { x = MSG_BREAK; numclients--;}// якщо є рядок згодовуємо
MPI_Ssend(&x, 1, MPI_INT, src, TAG_MSG, MPI_COMM_WORLD);// її клієнту. Інакше (файл
// закінчився) гасимо клієнта.
if (allok)
{
acc_name_len = strlen(acc_name)+1, acc_pass_len = strlen(acc_pass)+1;
printf (">>> Feeding %s:: %s to proc %d\n",acc_name,acc_pass, src);fflush(stdout);
MPI_Ssend(&acc_name_len, 1, MPI_INT, src,TAG_SEND_NAMELEN, MPI_COMM_WORLD);
MPI_Ssend(&acc_pass_len, 1, MPI_INT, src,TAG_SEND_PASSLEN, MPI_COMM_WORLD);
MPI_Ssend(&acc_name, acc_name_len, MPI_CHAR, src, TAG_SEND_NAME, MPI_COMM_WORLD);
MPI_Ssend(&acc_pass, acc_pass_len, MPI_CHAR, src, TAG_SEND_PASS, MPI_COMM_WORLD);
}
break;
}
}
printf ("[%d] Process exits\n",myrank);fflush(stdout);
}
else
{
int acc_name_len, acc_pass_len;
while (1)
{
x = MSG_READY;
MPI_Ssend(&x, 1, MPI_INT, 0, TAG_MSG, MPI_COMM_WORLD);// Посилаємо сигнал готовності
printf("[%d] Waiting\n",myrank);fflush(stdout);
MPI_Recv(&x, 1, MPI_INT, 0, TAG_MSG, MPI_COMM_WORLD, &status);
if (x == MSG_BREAK) // Вирішуємо, що робити далі
{
printf("[%d] BREAK received \n",myrank);fflush(stdout);
break;
}
MPI_Recv(&acc_name_len, 1, MPI_INT, 0,TAG_SEND_NAMELEN, MPI_COMM_WORLD, &status);
MPI_Recv(&acc_pass_len, 1, MPI_INT, 0,TAG_SEND_PASSLEN, MPI_COMM_WORLD, &status);
MPI_Recv(&acc_name, acc_name_len, MPI_CHAR, 0, TAG_SEND_NAME, MPI_COMM_WORLD, &status);
MPI_Recv(&acc_pass, acc_pass_len, MPI_CHAR, 0, TAG_SEND_PASS, MPI_COMM_WORLD, &status);