omp paralelo frente a omp paralelo para

105

¿Cuál es la diferencia entre estos dos?

[UNA]

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

[SI]

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

Respuestas:

65

No creo que haya ninguna diferencia, uno es un atajo para el otro. Aunque su implementación exacta podría tratarlos de manera diferente.

Las construcciones de trabajo compartido en paralelo combinadas son un atajo para especificar una construcción en paralelo que contiene una construcción de trabajo compartido y no otras declaraciones. Las cláusulas permitidas son la unión de las cláusulas permitidas para las construcciones paralelas y de trabajo compartido.

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

Las especificaciones para OpenMP están aquí:

https://openmp.org/specifications/

Ade Miller
fuente
66

Estos son equivalentes.

#pragma omp parallelgenera un grupo de subprocesos, mientras que #pragma omp fordivide las iteraciones de bucle entre los subprocesos generados. Puede hacer ambas cosas a la vez con la #pragma omp parallel fordirectiva fusionada .

Krzysztof Kosiński
fuente
En mi código estoy usando esta misma estructura. Sin embargo, cuando utilizo la schedule(static, chunk)cláusula en la directiva, tengo un problema. El código funciona bien, pero cuando invoco este código desde un programa MPI, se ejecuta en un bucle infinito. El contador de bucle es cero en todas las iteraciones de este bucle. Tengo el contador de bucle definido como privado en la #pragma omp paralleldirectiva. No tengo idea de por qué solo falla cuando MPI invoca el código. Estoy algo seguro de que cada proceso MPI se ejecuta en un procesador diferente del clúster si eso importa. No tengo idea de si el horario está causando el problema.
Rohit Banga
Lo mismo funciona bien cuando uso la #pragma omp parallel fordirectiva. Debería haber alguna diferencia.
Rohit Banga
1
Actualización: Como resultado, estoy observando este problema solo cuando uso la cláusula de programación, así que supongo que no depende de si uso el paralelo combinado para o dos directivas diferentes.
Rohit Banga
28

Aquí hay un ejemplo de cómo usar separado parallely for aquí . En resumen, se puede utilizar para la asignación dinámica de matrices privadas de subprocesos de OpenMP antes de ejecutar el forciclo en varios subprocesos. Es imposible realizar la misma inicialización por parallel forsi acaso.

UPD: En el ejemplo de la pregunta no hay diferencia entre un pragma único y dos pragmas. Pero en la práctica, puede realizar un comportamiento más consciente de subprocesos con directivas paralelas y for separadas. Algún código por ejemplo:

#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
fuente
9

Aunque ambas versiones del ejemplo específico son equivalentes, como ya se mencionó en las otras respuestas, todavía hay una pequeña diferencia entre ellas. La primera versión incluye una barrera implícita innecesaria, que se encuentra al final del "omp para". La otra barrera implícita se puede encontrar al final de la región paralela. Agregar "nowait" a "omp for" haría que los dos códigos fueran equivalentes, al menos desde la perspectiva de OpenMP. Menciono esto porque un compilador OpenMP podría generar un código ligeramente diferente para los dos casos.

Phadjido
fuente
7

Veo tiempos de ejecución completamente diferentes cuando tomo un bucle for en g ++ 4.7.0 y 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];

el código de serie (no openmp ) se ejecuta en 79 ms. el código "paralelo para" se ejecuta en 29 ms. Si omito el fory uso#pragma omp parallel , el tiempo de ejecución se dispara hasta 179 ms, que es más lento que el código de serie. (la máquina tiene una concurrencia hw de 8)

el código enlaza con libgomp

parcomputar
fuente
2
Creo que es porque omp paralelo ejecuta el bucle en un hilo separado sin dividirlo en hilos, por lo que el hilo principal está esperando que termine el segundo hilo. y el tiempo se dedica a sincronizar.
Antigluk
7
Esto se debe a que sin un #pragma omp forbucle no hay ningún intercambio de subprocesos múltiples. Pero ese no fue el caso de los OP de todos modos, inténtelo de nuevo con una versión adicional #pragma omp fordentro #pragm omp parallely debería ejecutarse de manera similar (si no igual) a la #pragma omp parallel forversión.
Christian Rau
2
Veo esta respuesta como la mejor, ya que muestra que no son "equivalentes"
Científico fallido
6

Obviamente, hay muchas respuestas, pero esta la responde muy bien (con fuente)

#pragma omp forsolo delega partes del bucle para diferentes subprocesos en el equipo actual. Un equipo es el grupo de subprocesos que ejecutan el programa. Al inicio del programa, el equipo consta de un solo miembro: el hilo maestro que ejecuta el programa.

Para crear un nuevo equipo de subprocesos, debe especificar la palabra clave paralela. Se puede especificar en el contexto circundante:

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

y:

Qué son: paralelo, para y un equipo

La diferencia entre paralelo, paralelo para y para es la siguiente:

Un equipo es el grupo de subprocesos que se ejecutan actualmente. Al comienzo del programa, el equipo consta de un solo hilo. Una construcción paralela divide el hilo actual en un nuevo equipo de hilos durante la duración del siguiente bloque / declaración, después de lo cual el equipo se fusiona nuevamente en uno. for divide el trabajo del bucle for entre los hilos del equipo actual.

No crea hilos, solo divide el trabajo entre los hilos del equipo en ejecución. paralelo para es una abreviatura de dos comandos a la vez: paralelo y para. Paralelo crea un nuevo equipo y, para las divisiones, ese equipo maneja diferentes partes del ciclo. Si su programa nunca contiene una construcción paralela, nunca hay más de un hilo; el subproceso maestro que inicia el programa y lo ejecuta, como en los programas que no son subprocesos.

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

fogx
fuente