2011-03-13 36 views
8

¿Cuál es la forma correcta de paralelizar un bucle bidimensional vergonzosamente paralelo en OpenMP? El número de dimensiones se conoce en tiempo de compilación, pero las dimensiones serán grandes no. Cualquiera de ellos puede ser uno, dos o un millón. Ciertamente no quierobucle OpenMP anidado multidimensional

Pensamientos N omp parallel 's para un bucle de N dimensiones ...:

  • El problema es conceptualmente simple. Solo el bucle 'más grande' más externo necesita ser paralelizado, pero las dimensiones del bucle son desconocidas en tiempo de compilación y pueden cambiar.

  • ¿Establecerá dinámicamente omp_set_num_threads(1) y #pragma omp for schedule(static, huge_number) que ciertas paralelizaciones de bucle sean no operativas? ¿Esto tendrá efectos secundarios/gastos generales no deseados? Se siente como un kludge.

  • El OpenMP Specification (2.10, A.38, A.39) indica la diferencia entre el paralelismo anidado conforme y el no conforme, pero no sugiere el mejor enfoque para este problema.

  • Es posible volver a ordenar los bucles, pero puede provocar muchos errores de caché. Desenrollar es posible pero no trivial. ¿Hay otra manera?

Esto es lo que me gustaría poner en paralelo:

for(i0=0; i0<n[0]; i0++) { 
    for(i1=0; i1<n[1]; i1++) { 
    ... 
     for(iN=0; iN<n[N]; iN++) { 
     <embarrasingly parallel operations> 
     } 
    ... 
    } 
} 

Gracias!

+0

+1 para una pregunta bien presentada – pmg

+1

Obtener la respuesta correcta se trata de hacer la pregunta correcta. 'Por supuesto, no está de más consultar las especificaciones. :) – Ricky

Respuesta

8

La directiva collapse es probablemente lo que está buscando, como se describe here. Esto esencialmente formará un solo bucle, que luego se paralizará, y está diseñado exactamente para este tipo de situaciones. Entonces lo harías:

#pragma omp parallel for collapse(N) 
for(int i0=0; i0<n[0]; i0++) { 
    for(int i1=0; i1<n[1]; i1++) { 
    ... 
     for(int iN=0; iN<n[N]; iN++) { 
     <embarrasingly parallel operations> 
     } 
    ... 
    } 
} 

y listo todo.

+0

Gracias! Dang, eso es fácil. Vi eso, pensé que no funcionaría por alguna razón, luego me olvidé de eso. Sip. Parece estar bien. Y parece anidarlo con '#omp parallel {#omp for colapse {#omp parallel {#omp for collapse {...}}}}' es válido. No es una buena idea, pero es para la evaluación de funciones en conjuntos de datos grandes, por lo que f (g (x)) debería ser perfectamente válida. ¡Gracias de todos modos! – Ricky

+2

Dos cosas a tener en cuenta. Primero, la cláusula de colapso solo está en OpenMP V3.0 y superior. En segundo lugar, si bien no es necesario que las variables de iteración de bucle sean privadas cuando se utiliza la cláusula de colapso, si elimina la cláusula de colapso, será mejor que las declare como arriba (utilizando la sintaxis C99) o las ponga en una cláusula privada . De lo contrario, se compartirán y tendrás un problema. – ejd

+1

Usando gcc 4.4.4 que implementa 3.0. Gracias por recordarme revisar. Y me gusta '#pragma omp parallel default (none)', para que no te descuides. Además, para su información, resulta que el índice no puede ser un elemento de la matriz, es decir, 'int i [N]'. Error del compilador – Ricky