openmp kritis

Aug 19 2020

Mengikuti pertanyaan ini , untuk kode di bawah ini ( dari contoh dokumen 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);
}

Dapatkah saya menghapus bagian luar jika tes dan lakukan

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];
    }
}

Jawaban

1 cos_theta Aug 19 2020 at 16:53

Anda bisa, tetapi ini secara efektif menghasilkan eksekusi berurutan. Utas terus menunggu untuk memasuki bagian kritis sehingga hanya satu utas yang mengeksekusi badan perulangan pada satu waktu. Karenanya, Anda mendapatkan kinerja yang sama (mungkin lebih buruk karena overhead sinkronisasi) daripada loop serial biasa.

Contoh dari dokumen MS hanya melakukan sinkronisasi jika nilai maksimum baru telah ditemukan. Ini memungkinkan untuk memproses semua nilai yang lebih rendah hingga saat ini secara paralel.

Seperti yang disarankan dalam komentar, gunakan konstruksi reduksi.