PPC Prova 2
PPC Prova 2
PPC Prova 2
i. A prova possui 9 questões. As 8 primeiras valem 1pt cada. A questão 9 vale 2pts.
ii. Respostas devem estar em um arquivo de texto simples Aval1_SeuNome.txt conforme modelo
ao final.
iii. Todas as respostas devem vir acompanhadas de justificativas, obrigatoriamente. Respostas
sem justificativa serão desconsideradas, ou seja, 0pt (zero ponto) será atribuído à questão.
iv. Você só terá direito a efetuar um único upload do arquivo-resposta pelo SIGAA. O sistema não
permitirá novos envios substitutivos/corretivos.
v. O horário de prova será das 12h30 às 15h.
Questões
1. Qual o maior risco de mal funcionamento de um programa MPI que pode levar a resultados
errados (ou resultado algum)?
A. As race conditions que fazem com que processos concorrentes possam consumir variáveis que
estão simultaneamente sendo alteradas.
B. A possibilidade de deadlock quando dois ou mais processos ficam mutualmente bloqueados em
virtude de operações de comunicação point-to-point.
C. A possibilidade de deadlock quando dois ou mais processos ficam bloqueados em virtude de
operações de comunicação coletiva.
D. O mau design de solução paralela que exige que vários processos troquem uma quantidade
exagerada de dados, gerando overhead de comunicação em excesso.
E. O mal design de solução paralela que provoca um desbalanceamento exagerado de carga entre
os processos.
3. Assinale a alternativa que pode representar uma possível saída impressa pela execução
mpiexec -n 3 ... do programa abaixo.
#include <stdio.h>
#include <mpi.h>
int main(void) {
int comm_sz, my_rank, status, x, y, z;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
switch(my_rank) {
case 0:
x=0; y=1; z=2;
MPI_Bcast(&x, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Send(&y, 1, MPI_INT, 2, 43, MPI_COMM_WORLD);
MPI_Bcast(&z, 1, MPI_INT, 1, MPI_COMM_WORLD);
break;
case 1:
x=3; y=8; z=5;
MPI_Bcast(&x, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&y, 1, MPI_INT, 1, MPI_COMM_WORLD);
break;
case 2:
x=6; y=7; z=8;
MPI_Bcast(&z, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Recv(&x, 1, MPI_INT, 0, 43, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Bcast(&y, 1, MPI_INT, 1, MPI_COMM_WORLD);
break;
}
printf("| %d %d %d ", x, y, z);
MPI_Finalize();
return 0;
}
A. | 0 1 8 | 0 8 5 | 1 8 0
B. | 0 1 8
C. | 0 1 2 | 3 8 5 | 6 7 8
D. | 3 7 8 | 3 7 8 | 3 7 8
E. | 3 7 8
Observe o código a seguir escrito em MPI C (as chamadas sleep(..) servem para simular o
tempo de execução de cada operação) e responda às questões 4, 5 e 6.
#include <stdio.h>
#include <mpi.h>
#include <unistd.h>
void op0(void) {sleep(1);}
void op1(void) {sleep(2);}
void op2(void) {sleep(4);}
int main(void) {
int m, local_m, n, local_n;
int my_rank, comm_sz;
MPI_Comm comm;
MPI_Init(NULL, NULL);
comm = MPI_COMM_WORLD;
MPI_Comm_size(comm, &comm_sz);
MPI_Comm_rank(comm, &my_rank);
double local_start, local_finish, local_elapsed;
double elapsed = 0.0;
MPI_Barrier(comm);
local_start = MPI_Wtime();
if (my_rank == 0)
op0();
if (my_rank == 1)
op1();
if (my_rank == 2)
op2();
local_finish = MPI_Wtime();
local_elapsed = local_finish - local_start;
MPI_Reduce(&local_elapsed, &elapsed, 1, MPI_DOUBLE, MPI_MAX, 0, comm);
if (my_rank == 0)
printf("%.1f\n", elapsed);
MPI_Finalize();
return 0;
}
A. 1.0
B. 2.0
C. 4.0
D. 7.0
E. Não determinístico. Poderia ser qualquer um dos 4 tempos acima sugeridos.
5. Se comentássemos todas as quatro linhas contendo if (ou seja, as operações op0(), op1(),
op2() e printf(...) seriam executadas incondicionalmente), qual alternativa melhor representa o
que seria impresso ao fim da execução?
A. 1.0 2.0 4.0
B. 7.0 7.0 7.0
C. 0.0 7.0 0.0
D. 0.0 0.0 4.0
E. 4.0 4.0 4.0
#include <stdio.h>
#include <mpi.h>
int main(void) {
int my_rank, comm_sz, x, a, b, c;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
if (my_rank == 0) scanf("%d %d", &x, &c);
MPI_Bcast(&x, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&c, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (my_rank == 0) {x++; printf("| x = %d ", x);}
if (my_rank == 1) {a = x+2; printf("| a = %d ", a);}
if (my_rank == 2) {b = a+3; printf("| b = %d ", b);}
if (my_rank == 3) {c++; printf("| c = %d ", c);}
MPI_Finalize();
return 0;
}
A. Independente dos valores finais das variáveis, qualquer execução geraria a mesma sequência de
impressão: | x = ... | a = ... | b = ... | c = ...
B. Os valores finais de x e c estariam corretos mas os de a e b não necessariamente.
C. Nenhum dos valores estaria necessariamente correto.
D. Todos os valores estariam corretos, mas a ordem de impressão poderia variar.
E. Execuções diferentes podem levar a valores finais diferentes para uma ou mais variáveis.
#include <stdio.h>
#include <mpi.h>
int main(void) {
int my_rank, comm_sz, x, a, b, c;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
if (my_rank == 0) {
scanf("%d %d", &x, &c);
x++;
MPI_Send(&x, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send(&c, 1, MPI_INT, 3, 0, MPI_COMM_WORLD);
printf("| x = %d ", x);
} else if (my_rank == 1) {
MPI_Recv(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
a = x+2;
MPI_Send(&a, 1, MPI_INT, 2, 0, MPI_COMM_WORLD);
printf("| a = %d ", a);
} else if (my_rank == 2) {
MPI_Recv(&a, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
b = a+3;
printf("| b = %d ", b);
} else if (my_rank == 3) {
MPI_Recv(&c, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
c++;
printf("| c = %d ", c);
}
MPI_Finalize();
return 0;
}
9. Crie uma versão alternativa de paralelização para o código anterior que permita que todos
os 4 processos envolvidos possam executar suas operações com o máximo de
independência uns dos outros e, ainda assim, preservar os valores finais das variáveis
geradas pela versão sequencial. [OBS: Você pode reutilizar o código anterior para escrever o
seu, eventualmente riscando ou modificando trechos indesejados ou adicionando novos
trechos e apontando claramente a inclusão feita entre linhas existentes. Você deve manter o
uso de comunicação point-to-point ao invés da coletiva.].
OBS: obviamente, as letras assinaladas neste modelo são apenas ilustrativas e não necessariamente
correspondem à alternativa correta da respectiva questão.