2009-09-19 10 views
74

¿Cuál es la diferencia entre estos dos?omp paralelo vs. omp paralelo para

[A]

#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) 
{ 
    ... 
} 

Respuesta

50

No creo que hay alguna diferencia, se trata de un acceso directo para el otro. Aunque su implementación exacta podría tratarlos de manera diferente.

Los constructos de trabajo compartido paralelos combinados son un acceso directo para la especificación de un constructo que contiene uno paralelo trabajo compartido construir y no hay otros estados. Las cláusulas permitidas son la unión de las cláusulas permitidas para las construcciones paralelas y de compartición de trabajo.

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

Las especificaciones de OpenMP son aquí:

http://openmp.org/wp/openmp-specifications/

44

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 directiva fusionada #pragma omp parallel for.

+0

En mi código estoy usando esta misma estructura. Sin embargo, cuando uso la cláusula 'schedule (static, chunk)' en la directiva, aparece 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 directiva '#pragma omp parallel'. No tengo idea de por qué solo falla cuando MPI invoca el código. De alguna manera estoy seguro de que cada proceso de MPI se ejecuta en un procesador diferente del clúster si eso es importante. No tengo idea de si el horario está causando el problema. –

+0

Lo mismo funciona bien cuando uso la directiva '#pragma omp parallel for'. Debería haber alguna diferencia. –

+1

Actualización: Como resultado, estoy observando este problema solo cuando uso la cláusula schedule así que supongo que no depende de si uso el paralelo combinado para o dos directivas diferentes. –

2

estoy viendo totalmente diferentes tiempos de ejecución cuando tomo un bucle en g ++ 4.7.0 y el uso de

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 (sin openmp) se ejecuta en 79 ms. el código "paralelo para" se ejecuta en 29 ms. Si omito 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 concurrencia hw de 8)

los enlaces de código para libgomp

+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 pasa en la sincronización. – Antigluk

+6

Esto se debe a que sin un '#pragma omp for' no hay ningún intercambio múltiple de subprocesos en absoluto. Pero ese no era el caso de OPs de todos modos, intente de nuevo con un '#pragma omp for' adicional dentro del' #pragm omp parallel' y debería ejecutarse de manera similar (si no es lo mismo) como la versión '#pragma omp parallel for' . –

+0

Veo esta respuesta como la mejor ya que muestra que no son "equivalentes" –

19

Aquí es ejemplo del uso separado parallel y forhere. En resumen, se puede usar para la asignación dinámica de matrices OpenMP de hilos privados antes de ejecutar el ciclo for en varios hilos. Es imposible hacer la misma inicialización en el caso parallel for.

UPD: En el ejemplo de la pregunta, no hay diferencia entre pragma simple y dos pragmas. Pero en la práctica puede realizar un comportamiento más atento a los subprocesos con paralelo separado y para las directivas. Algunos 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 
} 
4

Aunque ambas versiones del ejemplo específico son equivalentes, como ya se ha mencionado en las otras respuestas, todavía hay una pequeña diferencia entre ellos. La primera versión incluye una barrera implícita innecesaria, que se encuentra al final de la "omp for". 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 una perspectiva OpenMP.Menciono esto porque un compilador OpenMP podría generar código ligeramente diferente para los dos casos.

Cuestiones relacionadas