omp paralelo vs. omp paralelo para

105

Qual é a diferença entre esses dois?

[UMA]

#pragma omp parallel
{ 
    #pragma omp for
    for(int i = 1; i < 100; ++i)
    {
        ...
    }
}

[B]

#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
   ...
}
Hyunjik Bae
fonte

Respostas:

65

Não acho que haja diferença, um é um atalho para o outro. Embora sua implementação exata possa lidar com eles de maneira diferente.

As construções de compartilhamento de trabalho paralelo combinadas são um atalho para especificar uma construção paralela contendo uma construção de compartilhamento de trabalho e nenhuma outra instrução. As cláusulas permitidas são a união das cláusulas permitidas para os construtos paralelos e de compartilhamento de trabalho.

Retirado de http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf

As especificações do OpenMP estão aqui:

https://openmp.org/specifications/

Ade Miller
fonte
66

Eles são equivalentes.

#pragma omp parallelgera um grupo de threads, enquanto #pragma omp fordivide iterações de loop entre as threads geradas. Você pode fazer as duas coisas ao mesmo tempo com a #pragma omp parallel fordiretiva fundida .

Krzysztof Kosiński
fonte
No meu código, estou usando essa mesma estrutura. No entanto, quando eu uso a schedule(static, chunk)cláusula em para diretiva, tenho um problema. O código funciona bem, mas quando estou invocando esse código de um programa MPI, ele executa um loop infinito. O contador de loop é zero em todas as iterações deste loop. Eu tenho o contador de loop definido como privado na #pragma omp paralleldiretiva. Não tenho ideia de por que ele só falha quando o MPI está invocando o código. Tenho certeza de que cada processo MPI está sendo executado em um processador diferente do cluster, se isso importa. Não tenho ideia se a programação está causando o problema.
Rohit Banga,
A mesma coisa funciona bem quando uso a #pragma omp parallel fordiretiva. Deve haver alguma diferença.
Rohit Banga,
1
Atualização: como se constatou, estou observando esse problema apenas quando uso a cláusula de programação, então acho que não depende de eu usar o paralelo combinado para ou duas diretivas diferentes.
Rohit Banga,
28

Aqui está um exemplo de uso de separado parallele for aqui . Resumindo, ele pode ser usado para alocação dinâmica de arrays privados de threads do OpenMP antes de executar o forciclo em várias threads. É impossível fazer a mesma inicialização no parallel forcaso.

UPD: No exemplo da pergunta, não há diferença entre o pragma único e dois pragmas. Mas, na prática, você pode criar um comportamento mais ciente de thread com paralelas separadas e para diretivas. Alguns códigos, por exemplo:

#pragma omp parallel
{ 
    double *data = (double*)malloc(...); // this data is thread private

    #pragma omp for
    for(1...100) // first parallelized cycle
    {
    }

    #pragma omp single 
    {} // make some single thread processing

    #pragma omp for // second parallelized cycle
    for(1...100)
    {
    }

    #pragma omp single 
    {} // make some single thread processing again

    free(data); // free thread private data
}
NtsDK
fonte
9

Embora as duas versões do exemplo específico sejam equivalentes, conforme já mencionado nas demais respostas, ainda há uma pequena diferença entre elas. A primeira versão inclui uma barreira implícita desnecessária, encontrada no final do "omp para". A outra barreira implícita pode ser encontrada no final da região paralela. Adicionar "nowait" a "omp for" tornaria os dois códigos equivalentes, pelo menos de uma perspectiva OpenMP. Menciono isso porque um compilador OpenMP pode gerar um código ligeiramente diferente para os dois casos.

phadjido
fonte
7

Estou vendo tempos de execução totalmente diferentes quando pego um loop for no g ++ 4.7.0 e uso

std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;

for (int i = 0; i < 5000000; i++)
{
   double r1 = ((double)rand() / double(RAND_MAX)) * 5;
   double r2 = ((double)rand() / double(RAND_MAX)) * 5;
   x.push_back(r1);
   y.push_back(r2);
}

int sz = x.size();

#pragma omp parallel for

for (int i = 0; i< sz; i++)
   prod[i] = x[i] * y[i];

o código serial (não openmp) roda em 79 ms. o código "paralelo para" é executado em 29 ms. Se eu omitir o fore usar #pragma omp parallel, o tempo de execução disparará para 179ms, que é mais lento do que o código serial. (a máquina tem simultaneidade hw de 8)

o código liga a libgomp

parcomputar
fonte
2
Acho que é porque o omp parallel executa o loop em thread separado sem dividi-lo em threads, então o thread principal está aguardando a conclusão do segundo thread. e o tempo gasta na sincronização.
Antigluk
7
Isso ocorre porque, sem um, #pragma omp fornão há compartilhamento multi-thread do loop. Mas esse não foi o caso do OPs de qualquer maneira, tente novamente com um adicional #pragma omp fordentro do #pragm omp parallele ele deve ser executado semelhante (se não o mesmo) à #pragma omp parallel forversão.
Christian Rau
2
Considero esta resposta a melhor, pois mostra que não são "equivalentes"
Failed Scientist
6

Obviamente, há muitas respostas, mas esta responde muito bem (com a fonte)

#pragma omp forapenas delega partes do loop para diferentes threads na equipe atual. Uma equipe é o grupo de threads que executam o programa. No início do programa, a equipe consiste em apenas um único membro: o thread mestre que executa o programa.

Para criar uma nova equipe de threads, você precisa especificar a palavra-chave parallel. Pode ser especificado no contexto circundante:

#pragma omp parallel
{
   #pragma omp for
   for(int n = 0; n < 10; ++n)
   printf(" %d", n);
}

e:

O que são: paralelo, para e uma equipe

A diferença entre paralelo, paralelo para e para é a seguinte:

Uma equipe é o grupo de threads que executam atualmente. No início do programa, a equipe consiste em um único thread. Uma construção paralela divide o encadeamento atual em uma nova equipe de encadeamentos durante o próximo bloco / instrução, após o qual a equipe volta a se fundir em um. for divide o trabalho do for-loop entre os threads da equipe atual.

Ele não cria threads, apenas divide o trabalho entre as threads da equipe em execução no momento. paralelo para é uma abreviação para dois comandos ao mesmo tempo: paralelo e para. Paralelo cria uma nova equipe e divide essa equipe para lidar com diferentes partes do loop. Se seu programa nunca contém uma construção paralela, nunca haverá mais de um thread; o thread mestre que inicia o programa e o executa, como em programas sem threads.

https://bisqwit.iki.fi/story/howto/openmp/

fogx
fonte