¿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)
{
...
}
¿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)
{
...
}
Respuestas:
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í:
Estos son equivalentes.
#pragma omp parallel
genera un grupo de subprocesos, mientras que #pragma omp for
divide las iteraciones de bucle entre los subprocesos generados. Puede hacer ambas cosas a la vez con la #pragma omp parallel for
directiva fusionada .
#pragma omp parallel for
directiva. Debería haber alguna diferencia.
Aquí hay un ejemplo de cómo usar separado parallel
y for
aquí . En resumen, se puede utilizar para la asignación dinámica de matrices privadas de subprocesos de OpenMP antes de ejecutar el for
ciclo en varios subprocesos. Es imposible realizar la misma inicialización por parallel for
si 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
}
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.
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 for
y 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
#pragma omp for
bucle 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 for
dentro #pragm omp parallel
y debería ejecutarse de manera similar (si no igual) a la #pragma omp parallel for
versión.
Obviamente, hay muchas respuestas, pero esta la responde muy bien (con fuente)
#pragma omp for
solo 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.
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 parallel
directiva. 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.