[Resultado do Desafio] Programação paralela com o OpenMP
- por Sergio Prado
E vamos lá para o resultado do desafio de programação paralela com o OpenMP.
A idéia do desafio era paralelizar um programa de cálculo do número PI com o framework de programação paralela OpenMP.
Recebi 10 submissões e o resultado foi bastante apertado. Todos os participantes conseguiram de alguma forma paralelizar a execução da aplicação, porém alguns se destacaram e ficaram abaixo da casa dos 2.7 segundos.
Os testes foram realizados em uma Raspberry Pi 3, e para garantir que não teria nenhuma aplicação rodando em paralelo e competindo em recursos com a aplicação, criei uma distribuição mínima com o Buildroot, de forma que eu tivesse apenas uma aplicação de terminal rodando para testar as aplicações.
Para realizar os testes, criei um shell script (abaixo) para rodar cada aplicação 5 vezes e armazenar o resultado em um arquivo de log. Depois analisei os arquivos de log e selecionei o menor tempo de execução de cada aplicação.
#!/bin/sh rm -rf openmp/*.log for f in `find openmp/* -name "*"`; do echo "Running $f" for i in `seq 1 5`; do { time $f 8000 ; } 2>> $f.log done done |
E desta vez tivemos dois vencedores, Phillipe Magalhaes e Daniel Junho, ambos com um tempo de execução de 2.66 segundos!
O George Tavares, vencedor do desafio de janeiro, ficou em terceiro com o tempo de 2.68 segundos, quase um empate técnico! Como a diferença era mínima (20 milissegundos) executei as três aplicações mais algumas vezes para garantir que realmente existia esta diferença de alguns milissegundos, o que foi confirmado após os testes.
Seguem os trechos de código-fonte otimizados pelos três primeiros colocados:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/* Phillipe Magalhaes */ #pragma omp parallel for shared (n,pi) private (i,j,r) schedule (dynamic,1) num_threads(omp_get_max_threads()) for (i = 0; i < n; i++) { r = 2; for (j = i; j ; j--) r = 2 + sqrt(r); r = sqrt(r); #pragma omp critical pi *= (r / 2); } /* Daniel Junho */ #pragma omp parallel for private(r, i, j) shared(pi) schedule(dynamic) for (i = 0; i < n; i++) { r = 2; for (j = i; j ; j--) r = 2 + sqrt(r); r = sqrt(r); #pragma omp critical { pi *= (r / 2); } } /* George Tavares */ #pragma omp parallel for ordered private( i, j, r) reduction(*:pi) schedule(dynamic) for (i = 0; i < n; i++) { r = 2; for (j = i; j ; j--) r = 2 + sqrt(r); r = sqrt(r); #pragma omp ordered pi *= (r / 2); } |
Os dois vencedores (Phillipe Magalhaes e Daniel Junho) ganharam os 10 pontos no ranking de desafios do blog, e todos os outros participantes ganharam 5 pontos.
Este é o ranking atualizado:
1. George Tavares 15 pontos 2. Daniel Junho 10 pontos 3. Phillipe Magalhães 10 pontos 4. Cleiton Bueno 5 pontos 5. Daniel Silva 5 pontos 6. Fábio Pereira 5 pontos 7. Fernando Mendonça 5 pontos 8. Gabriel Almeida 5 pontos 9. João Marcelo 5 pontos 10. Luis Antônio 5 pontos 11. Marcelo Centenaro 5 pontos |
E o ganhador da Beaglebone White, sorteado no RANDOM.ORG, foi o Daniel Junho!
Obrigado pela participação de todos! E para aqueles que não conheciam, espero tenham aprendido um pouco sobre como paralelizar a execução de aplicações C/C++ com o OpenMP.
Na semana que vem divulgarei o próximo desafio.
Um abraço e até lá!
Sergio Prado
Sem Comentários
Nenhum comentário até agora... é a sua chance de ser o primeiro a comentar!