MPI Pi calculation
-
Upload
rafael-salema-marques -
Category
Documents
-
view
6 -
download
0
description
Transcript of MPI Pi calculation
![Page 1: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/1.jpg)
INSTITUTO TECNOLÓGICO DE AERONÁUTICA
Avenida Marechal Eduardo Gomes, S/N' – DCTA – São José dos Campos – SP
CE-265 – Processamento paralelo
Exercício #5
Professor: Dr. Jairo Panetta
Alunos: Rafael Salema Marques
02 de abril de 2015
![Page 2: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/2.jpg)
2
SUMÁRIO
1 VERSÃO PARALELA SeqPi.c ......................................................................................... 3
2 ARQUIVO DE SAÍDA (Pi_1M_2^30.out) ....................................................................... 7
3 ARQUIVO DE SAÍDA (Pi_2M_2^30.out) ....................................................................... 7
4 ARQUIVO DE SAÍDA (Pi_4M_2^30.out) ....................................................................... 7
5 ARQUIVO DE SAÍDA (Pi_8M_2^30.out) ....................................................................... 8
6 SpeedUp .............................................................................................................................. 8
7 Análise de resultados .......................................................................................................... 9
![Page 3: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/3.jpg)
3
1 VERSÃO PARALELA SeqPi.c
#include <math.h> #include <stdio.h> #include <stdlib.h> #include <mpi.h> float wall_time(void); // inCircle: generate "points" random points at domain // (xStart, yStart) : (xStart+xRange, yStart+yRange), // that is a part of the square (-1.,-1):(1,1) and // count how many of these points lye inside the // unit circle long inCircle(long points, // # random pairs to generate float xStart, // start point at x domain float xRange, // range of x domain float yStart, // start point at y domain float yRange) // range of y domain { long count; long inside; int randVal; float xRand; float yRand; // random point is (xStart,yStart) + random fraction // of (xRange,yRange); // inside unit circle iff distance to origin <= 1.0 inside=0; for (count=0; count<points; count++) { randVal=rand(); xRand = xStart + xRange*(float)randVal/(float)RAND_MAX; randVal=rand(); yRand = yStart + yRange*(float)randVal/(float)RAND_MAX; if (xRand*xRand + yRand*yRand <= 1.0) inside++; } return inside; } int main(int argc, char *argv[]) { int procs=1; int pow; float xStart, xRange; float yStart, yRange; long points; long inside;
![Page 4: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/4.jpg)
4
float tend, tstart; double computedPi, referencePi, relError; int root=0; int i; double pi_arr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; double somaPi; double mediaPi; /////////////////////////////////////////////////////////////////////////////// // input arguments /////////////////////////////////////////////////////////////////////////////// if (argc != 2) { printf(" use: <exec> <exponent> (range [0:30]) \n"); return -1; } pow = atoi(argv[1]); if (pow < 0 || pow > 30) { printf(" exponent (%d) outside range [0:30] \n", pow); return -1; } points = 1L << pow; /////////////////////////////////////////////////////////////////////////////// // Inicializando MPI /////////////////////////////////////////////////////////////////////////////// MPI_Init(NULL, NULL); int size; MPI_Comm_size(MPI_COMM_WORLD, &size); int id; MPI_Comm_rank(MPI_COMM_WORLD, &id); // Get the name of the processor char processor_name[MPI_MAX_PROCESSOR_NAME]; int name_len; MPI_Get_processor_name(processor_name, &name_len); //printf("Inicializado a partir do processador %s, com o id #%d de um total de
%d processadores\n", processor_name, id, size); float dominio; float tamLocal; float inicio; dominio = 2; tamLocal = dominio/size;
![Page 5: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/5.jpg)
5
///////////////////////////////////////////////////////////// // divisão do domínio X ///////////////////////////////////////////////////////////// inicio = -1; inicio = inicio + (tamLocal * id); printf("id# %d inicio=%f no eixo x e range=%f\n", id, inicio, tamLocal); ///////////////////////////////////////////////////////////// // square that circumscribes unit circle ///////////////////////////////////////////////////////////// xStart=inicio; xRange=tamLocal; yStart=-1.0; yRange=2.0; //divide a quantidade de pontos pela quantidade de processos points = points/size; ///////////////////////////////////////////////////////////// // compute pi and measure execution time ///////////////////////////////////////////////////////////// tstart = wall_time(); inside = inCircle(points, xStart, xRange, yStart, yRange); computedPi = 4.0* ((double)inside/(double)points); tend = wall_time() - tstart; ///////////////////////////////////////////////////////////////////////// MPI_Send(&computedPi, 1, MPI_DOUBLE, 0, id, MPI_COMM_WORLD); printf("id# %d enviou a mensagem de computedPi=(%f) para o id# %d \n", id,
computedPi, root); //aguarda todos enviarem a mensagem MPI_Barrier( MPI_COMM_WORLD ); if (id == root) { for (i=0; i < size; i++) { if (i == 0) { pi_arr[0] = computedPi; printf("id# %d calculou computedPi=(%f)\n", id, pi_arr[i]); somaPi = somaPi + pi_arr[0]; } else { MPI_Recv(&pi_arr[i], 1, MPI_DOUBLE, i, i, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
![Page 6: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/6.jpg)
6
printf("id# %d recebeu a mensagem de computedPi=(%f) do id# %d \n", id, pi_arr[i], i);
somaPi = somaPi + pi_arr[i]; } } printf("Pi medio=%9.7f\n", somaPi/size); mediaPi = somaPi / size; // relative error and final dump referencePi = 2.0*asin(1.0); printf("Pi referencia=%9.7f\n", referencePi); relError = 100.0*fabs(mediaPi-referencePi)/referencePi; printf("pi=%9.7f, rel error %8.4f%%, %d procs, 2^%d points, %f(s) exec
time\n\n", mediaPi, relError, size, pow, tend); } MPI_Finalize(); return 0; }
![Page 7: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/7.jpg)
7
2 ARQUIVO DE SAÍDA (Pi_1M_2^30.out)
id# 0 inicio=-1.000000 no eixo x e range=2.000000
id# 0 enviou a mensagem de computedPi=(3.141590) para o id# 0
id# 0 calculou computedPi=(3.141590)
Pi medio=3.1415903
Pi referencia=3.1415927
pi=3.1415903, rel error 0.0001%, 1 procs, 2^30 points, 88.913216(s) exec time
3 ARQUIVO DE SAÍDA (Pi_2M_2^30.out)
id# 0 inicio=-1.000000 no eixo x e range=1.000000
id# 1 inicio=0.000000 no eixo x e range=1.000000
id# 0 enviou a mensagem de computedPi=(3.141682) para o id# 0
id# 1 enviou a mensagem de computedPi=(3.141540) para o id# 0
id# 0 calculou computedPi=(3.141682)
id# 0 recebeu a mensagem de computedPi=(3.141540) do id# 1
Pi medio=3.1416115
Pi referencia=3.1415927
pi=3.1416115, rel error 0.0006%, 2 procs, 2^30 points, 44.663998(s) exec time
4 ARQUIVO DE SAÍDA (Pi_4M_2^30.out)
id# 0 inicio=-1.000000 no eixo x e range=0.500000
id# 2 inicio=0.000000 no eixo x e range=0.500000
id# 3 inicio=0.500000 no eixo x e range=0.500000
id# 1 inicio=-0.500000 no eixo x e range=0.500000
id# 2 enviou a mensagem de computedPi=(3.826524) para o id# 0
id# 1 enviou a mensagem de computedPi=(3.826386) para o id# 0
id# 0 enviou a mensagem de computedPi=(2.456891) para o id# 0
id# 3 enviou a mensagem de computedPi=(2.456804) para o id# 0
id# 0 calculou computedPi=(2.456891)
id# 0 recebeu a mensagem de computedPi=(3.826386) do id# 1
id# 0 recebeu a mensagem de computedPi=(3.826524) do id# 2
id# 0 recebeu a mensagem de computedPi=(2.456804) do id# 3
Pi medio=3.1416511
Pi referencia=3.1415927
pi=3.1416511, rel error 0.0019%, 4 procs, 2^30 points, 22.659994(s) exec time
![Page 8: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/8.jpg)
8
5 ARQUIVO DE SAÍDA (Pi_8M_2^30.out)
id# 4 inicio=0.000000 no eixo x e range=0.250000
id# 2 inicio=-0.500000 no eixo x e range=0.250000
id# 0 inicio=-1.000000 no eixo x e range=0.250000
id# 5 inicio=0.250000 no eixo x e range=0.250000
id# 7 inicio=0.750000 no eixo x e range=0.250000
id# 1 inicio=-0.750000 no eixo x e range=0.250000
id# 3 inicio=-0.250000 no eixo x e range=0.250000
id# 6 inicio=0.500000 no eixo x e range=0.250000
id# 4 enviou a mensagem de computedPi=(3.957918) para o id# 0
id# 3 enviou a mensagem de computedPi=(3.957937) para o id# 0
id# 2 enviou a mensagem de computedPi=(3.694909) para o id# 0
id# 5 enviou a mensagem de computedPi=(3.695029) para o id# 0
id# 6 enviou a mensagem de computedPi=(3.100309) para o id# 0
id# 1 enviou a mensagem de computedPi=(3.100370) para o id# 0
id# 0 enviou a mensagem de computedPi=(1.813289) para o id# 0
id# 7 enviou a mensagem de computedPi=(1.813330) para o id# 0
id# 0 calculou computedPi=(1.813289)
id# 0 recebeu a mensagem de computedPi=(3.100370) do id# 1
id# 0 recebeu a mensagem de computedPi=(3.694909) do id# 2
id# 0 recebeu a mensagem de computedPi=(3.957937) do id# 3
id# 0 recebeu a mensagem de computedPi=(3.957918) do id# 4
id# 0 recebeu a mensagem de computedPi=(3.695029) do id# 5
id# 0 recebeu a mensagem de computedPi=(3.100309) do id# 6
id# 0 recebeu a mensagem de computedPi=(1.813330) do id# 7
Pi medio=3.1416365
Pi referencia=3.1415927
pi=3.1416365, rel error 0.0014%, 8 procs, 2^30 points, 11.868585(s) exec time
6 SpeedUp
2^30 Proc (qtd) 1 2 4 8 Tempo (s) 88.957489 45.489933 23.896288 11.999891 speedup 1 1,955542 3,722648 7,413191
Observando a tabela acima, obtivemos uma melhora considerável de performance com a
![Page 9: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/9.jpg)
9
divisão do domínio aplicada ao eixo X, resultados muito próximos aos casos ideais de
speedup, que seriam respectivamente 1, 2, 4 e 8.
7 Relação Erro x Quantidade de Processos
O programa faz uso de uma relação da entre o espalhamento
aleatório de pontos em uma área de um círculo de raio = 1 inscrito em
um quadrado para calcular Pi.
Essa relação leva em consideração a quantidade de pontos que
estão dentro ou fora da área do círculo.
A partir do momento em que se particiona o domínio (no presente caso o eixo X), cada
processo de nosso programa passa a tratar subdomínios diferentes no que diz respeito a
relação da área do círculo inscrito no quadrado, e consequentemente diferentes probabilidades
do ponto aleatório estar dentro ou fora da área do círculo.
Outro fato interessante que foi observado é que o erro tende a aumentar com a
quantidade de processos em paralelo. Salvo melhor juízo, entendo que quanto mais se divide
o domínio, mais heterogêneas serão as áreas para cálculo de Pi de cada processo, o que gera
valores diferentes no cálculo.
Por exemplo:
Para m=2 e n=30 o domínio X será dividido em 2 partes iguais da seguinte forma: Processo 0 1
Domínio -1.00 a 0.00 0.00 a 1.00
Cálculo de Pi 3.141682 3.141540
• Pi referência: 3.1415927 / Pi médio encontrado: 3.1416115
• Erro: 0.0006%
Para m=8 e n=30 o domínio X será dividido em 8 partes iguais da seguinte forma:
Processo 0 1 2 3 4 5 6 7
Domínio -1.00 a
-0.75
-0.75 a
-0.50
-0.50 a
-0.25
-0.25 a
0.00
0.00 a
0.25
0.25 a
0.50
0.50 a
0.75
0.75 a
1.00
Cálculo de Pi 1.813289 3.100370 3.694909 3.957937 3.957918 3.695029 3.100309 1.813330
• Pi referência: 3.1415927 / Pi médio encontrado: 3.1416365
• Erro: 0.0014%
![Page 10: MPI Pi calculation](https://reader034.fdocuments.in/reader034/viewer/2022051417/55cf8fec550346703ba15403/html5/thumbnails/10.jpg)
10
Como podemos perceber relacionando as informações das tabelas acima e o gráfico a
baixo, o cálculo de Pi dos processos (0 e 7), (1 e 6), (2 e 5) e (3 e 4) são similares entre si,
bem como seus domínios. Fato que corrobora a hipótese da área do circulo dentro do domínio
interferir diretamente no resultado de Pi. Ou seja, Pi é proporcional a área do círculo no
domínio.
Por fim, conclui-se que quanto maior a diferença dos valores de Pi nos subdomínios
maior será o erro. Consequentemente, quanto maior for a quantidade de processos, maior será
a diferença entre o menor Pi computado e o maior, aumentando assim o erro.
Acredito ainda que o arredondamento dos cálculos também contribui de forma modesta
com o erro no resultado final.
0,000000
1,000000
2,000000
3,000000
4,000000
5,000000
0 1 2 3 4 5 6 7
pi
pi