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)
{
...
}
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)
{
...
}
Respostas:
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:
Eles são equivalentes.
#pragma omp parallel
gera um grupo de threads, enquanto #pragma omp for
divide iterações de loop entre as threads geradas. Você pode fazer as duas coisas ao mesmo tempo com a #pragma omp parallel for
diretiva fundida .
#pragma omp parallel for
diretiva. Deve haver alguma diferença.
Aqui está um exemplo de uso de separado parallel
e for
aqui . Resumindo, ele pode ser usado para alocação dinâmica de arrays privados de threads do OpenMP antes de executar o for
ciclo em várias threads. É impossível fazer a mesma inicialização no parallel for
caso.
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
}
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.
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 for
e 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
#pragma omp for
nã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 for
dentro do #pragm omp parallel
e ele deve ser executado semelhante (se não o mesmo) à #pragma omp parallel for
versão.
Obviamente, há muitas respostas, mas esta responde muito bem (com a fonte)
#pragma omp for
apenas 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.
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 parallel
diretiva. 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.