openmp critico

Aug 19 2020

Siguiendo esta pregunta , para el código siguiente ( del ejemplo de documentos de MS OpenMP )

// omp_critical.cpp
// compile with: /openmp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

#define SIZE 10

int main()
{
    int i;
    int max;
    int a[SIZE];

    for (i = 0; i < SIZE; i++)
    {
        a[i] = rand();
        printf_s("%d\n", a[i]);
    }

    max = a[0];
    #pragma omp parallel for num_threads(4)
    for (i = 1; i < SIZE; i++)
    {
        if (a[i] > max)
        {
            #pragma omp critical
            {
                // compare a[i] and max again because max
                // could have been changed by another thread after
                // the comparison outside the critical section
                if (a[i] > max)
                    max = a[i];
            }
        }
    }

    printf_s("max = %d\n", max);
}

¿Puedo quitar el exterior si prueba y hago

max = a[0];
#pragma omp parallel for num_threads(4)
for (i = 1; i < SIZE; i++)
{
    #pragma omp critical
    {
        // compare a[i] and max again because max
        // could have been changed by another thread after
        // the comparison outside the critical section
        if (a[i] > max)
            max = a[i];
    }
}

Respuestas

1 cos_theta Aug 19 2020 at 16:53

Puede, pero esto da como resultado una ejecución secuencial. Los subprocesos están constantemente esperando para ingresar a la sección crítica de modo que solo un subproceso ejecuta el cuerpo del bucle a la vez. Por lo tanto, obtiene el mismo rendimiento (tal vez incluso peor debido a la sobrecarga de sincronización) que un bucle en serie simple.

El ejemplo de MS docs solo se sincroniza si se ha encontrado un nuevo valor máximo. Esto permite procesar todos los valores más bajos hasta este punto en paralelo.

Como se sugiere en los comentarios, use una construcción de reducción.