Pregunta

Soy bastante nuevo en OpenMP y estoy intentando iniciar un hilo individual para procesar cada elemento en una matriz 2D.

Básicamente, esto:

for (i = 0; i < dimension; i++) {
    for (int j = 0; j < dimension; j++) {
        a[i][j] = b[i][j] + c[i][j];

Lo que estoy haciendo es esto:

#pragma omp parallel for shared(a,b,c) private(i,j) reduction(+:diff) schedule(dynamic)
    for (i = 0; i < dimension; i++) {
        for (int j = 0; j < dimension; j++) {
            a[i][j] = b[i][j] + c[i][j];

¿Esto realmente inicia un hilo para cada elemento 2D o no?¿Cómo probaría eso?Si está mal ¿cuál es la forma correcta de hacerlo?¡Gracias!

Nota:El código se ha simplificado enormemente.

¿Fue útil?

Solución

Sólo el bucle externo es paralelo en su ejemplo de código.Puedes probar imprimiendo omp_get_thread_num() en el bucle interior y verás que, para un determinado i, el número de hilo es el mismo (por supuesto, esta prueba es demostrativa más que definitiva, ya que diferentes ejecuciones darán resultados diferentes).Por ejemplo, con:

#include <stdio.h>
#include <omp.h>
#define dimension 4

int main() {
    #pragma omp parallel for
    for (int i = 0; i < dimension; i++)
        for (int j = 0; j < dimension; j++)
            printf("i=%d, j=%d, thread = %d\n", i, j, omp_get_thread_num());
    }

Yo obtengo:

i=1, j=0, thread = 1
i=3, j=0, thread = 3
i=2, j=0, thread = 2
i=0, j=0, thread = 0
i=1, j=1, thread = 1
i=3, j=1, thread = 3
i=2, j=1, thread = 2
i=0, j=1, thread = 0
i=1, j=2, thread = 1
i=3, j=2, thread = 3
i=2, j=2, thread = 2
i=0, j=2, thread = 0
i=1, j=3, thread = 1
i=3, j=3, thread = 3
i=2, j=3, thread = 2
i=0, j=3, thread = 0

En cuanto al resto de su código, es posible que desee poner más detalles en una nueva pregunta (es difícil saberlo a partir de la pequeña muestra), pero, por ejemplo, no puede poner private(j) cuando j sólo se declara más tarde.Es automáticamente privado en mi ejemplo anterior.Supongo diff es una variable que no podemos ver en la muestra.Además, la variable de bucle i es automáticamente privado (desde el especificación de la versión 2.5 - lo mismo en la especificación 3.0)

La variable de iteración de bucle en el bucle de A para una construcción o paralela es privada en esa construcción.

Editar:Todo lo anterior es correcto para el código que tú y yo hemos mostrado, pero quizás te interese lo siguiente.Para OpenMP versión 3.0 (disponible, por ejemplo, en gcc versión 4.4, pero no la versión 4.3) hay una collapse cláusula donde podrías escribir el código como lo tienes, pero con#pragma omp parallel for collapse (2) para paralelizar ambos bucles for (ver la especificación).

Editar:Bien, descargué gcc 4.5.0 y ejecuté el código anterior, pero usando collapse (2) para obtener el siguiente resultado, que muestra el bucle interno ahora paralelizado:

i=0, j=0, thread = 0
i=0, j=2, thread = 1
i=1, j=0, thread = 2
i=2, j=0, thread = 4
i=0, j=1, thread = 0
i=1, j=2, thread = 3
i=3, j=0, thread = 6
i=2, j=2, thread = 5
i=3, j=2, thread = 7
i=0, j=3, thread = 1
i=1, j=1, thread = 2
i=2, j=1, thread = 4
i=1, j=3, thread = 3
i=3, j=1, thread = 6
i=2, j=3, thread = 5
i=3, j=3, thread = 7

Comentarios aquí (busque "Soluciones alternativas") también son relevantes para las soluciones alternativas en la versión 2.5 si desea paralelizar ambos bucles, pero la especificación de la versión 2.5 citada anteriormente es bastante explícita (consulte los ejemplos no conformes en la sección A.35).

Otros consejos

Usted puede tratar de utilizar Fors paralelas OMP anidada (después llamada omp_set_nested(1)), pero una no se admite en todas las implementaciones de OpenMP.

Así que supongo que para hacer algo de rejilla 2D y empezar todo de rosca en la parrilla de una sola para (ejemplo para la red fija hilo 4x4):

#pragma omp parallel for
for(k = 0; k < 16; k++)
{
    int i,j,i_min,j_min,i_max,j_max;
    i_min=(k/4) * (dimension/4);
    i_max=(k/4 + 1) * (dimension/4);
    j_min=(k%4) * (dimension/4);
    j_max=(k%4 + 1) * (dimension/4);

    for(i=i_min;i<i_max;i++)
      for(j=j_min;j<j_max;j++)
       f(i,j);

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top