openmp ที่สำคัญ

Aug 19 2020

ต่อไปนี้คำถามนี้สำหรับโค้ดด้านล่าง ( จาก 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);
}

ฉันสามารถถอดด้านนอกออกได้หรือไม่หากทดสอบและทำ

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

คำตอบ

1 cos_theta Aug 19 2020 at 16:53

คุณสามารถทำได้แต่ผลลัพธ์นี้มีประสิทธิภาพในการดำเนินการตามลำดับ เธรดกำลังรอที่จะเข้าสู่ส่วนวิกฤตอย่างต่อเนื่องโดยที่เธรดเพียงหนึ่งเธรดจะเรียกใช้เนื้อหาลูปในแต่ละครั้ง ดังนั้นคุณจะได้รับประสิทธิภาพที่เท่ากัน (อาจแย่กว่าเดิมเนื่องจากค่าโสหุ้ยการซิงโครไนซ์) มากกว่าการวนซ้ำแบบอนุกรมธรรมดา

ตัวอย่างจากเอกสาร MS จะซิงโครไนซ์เฉพาะเมื่อพบค่าสูงสุดใหม่ สิ่งนี้ช่วยให้สามารถประมวลผลค่าที่ต่ำกว่าทั้งหมดจนถึงจุดนี้แบบขนาน

ตามที่แนะนำในความคิดเห็นให้ใช้โครงสร้างการลด