[Resultado do Desafio] Programação paralela com o OpenMP

- por Sergio Prado

Categorias: Desafios Tags: ,

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!

Faça um Comentário

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.