수색…


비고

일반적인 함정은 병렬 영역의 모든 스레드가 작업을 인스턴스화 (생성)해야한다고 생각하는 것입니다. 그러나 스레드 수와 처리 할 요소 수를 곱한만큼의 작업을 생성하지 않는 한 일반적으로 그렇지 않습니다. 따라서 OpenMP 태스크 코드에서

#pragma omp parallel
#pragma omp single
...
   #pragma omp task
   { code for a given task; }
...

OpenMP 작업을 사용하는 C ++ 목록 컨테이너의 병렬 처리

#include <omp.h>
#include <unistd.h>
#include <iostream>
#include <list>

static void processElement (unsigned n)
{
    // Tell who am I. The #pragma omp critical ensures that
    // only one thread sends data to std::cout
    #pragma omp critical
    std::cout <<
      "Thread " << omp_get_thread_num() << " processing element " << n
      << std::endl;

    // Simulate some work
    usleep (n*1000);
}

int main (void)
{
    std::list<unsigned> lst;

    // Fill the list
    for (unsigned u = 0; u < 16; ++u)
            lst.push_back (1+u);

    // Now process each element of the list in parallel

    #pragma omp parallel  // Create a parallel region
    #pragma omp single    // Only one thread will instantiate tasks
    {
            for (auto element : lst)
            {
                    #pragma omp task firstprivate (element)
                    processElement (element);
            }

            // Wait for all tasks to be finished
            #pragma omp taskwait
    }

    return 0;
}

이 예제는 #pragma omp task 지시문을 사용하여 OpenMP 태스크 구문을 통해 병렬로 STL 목록 (코드에서 lst 의 처리를 시뮬레이트합니다. 예는 /은 각 요소에 대해 하나의 OpenMP 작업의 인스턴스를 생성 lst 하고 실행 준비로의 OpenMP 스레드가 즉시 작업을 실행합니다.

$ OMP_NUM_THREADS=4 ./a.out
Thread 0 processing element 16
Thread 3 processing element 3
Thread 2 processing element 1
Thread 1 processing element 2
Thread 2 processing element 4
Thread 1 processing element 5
Thread 3 processing element 6
Thread 2 processing element 7
Thread 1 processing element 8
Thread 3 processing element 9
Thread 2 processing element 10
Thread 1 processing element 11
Thread 0 processing element 15
Thread 3 processing element 12
Thread 2 processing element 13
Thread 1 processing element 14

OpenMP 작업을 사용하는 pi에 대한 재귀 계산

아래 코드는 재귀 적 접근 방식을 사용하여 PI 값을 계산합니다. MAX_PARALLEL_RECURSIVE_LEVEL 값을 수정하여 재귀 깊이에 따라 작업 생성을 중지하십시오. 재귀 적 응용 프로그램에서 병렬 처리를 작성하는이 접근법을 사용하면 작성하는 작업이 많을수록 생성되는 병렬 작업이 많아지고 작업 당 작업이 줄어 듭니다. 따라서 응용 프로그램을 시험하여 성능 향상 측면에서 추가 작업을 생성하는 수준을 이해하는 것이 편리합니다.

#include <stdio.h>
#include <omp.h>

double pi_r (double h, unsigned depth, unsigned maxdepth, unsigned long long begin, unsigned long long niters)
{
    if (depth < maxdepth)
    {
        double area1, area2;

        // Process first half
        #pragma omp task shared(area1)
        area1 = pi_r (h, depth+1, maxdepth, begin, niters/2-1);

        // Process second half
        #pragma omp task shared(area2)
        area2 = pi_r (h, depth+1, maxdepth, begin+niters/2, niters/2);

        #pragma omp taskwait

        return area1+area2;
    }
    else
    {

        unsigned long long i;
        double area = 0.0;

        for (i = begin; i <= begin+niters; i++)
        {
            double x = h * (i - 0.5);
            area += (4.0 / (1.0 + x*x));
        }

        return area;
    }
}

double pi (unsigned long long niters)
{
    double res;
    double h = 1.0 / (double) niters;

    #pragma omp parallel shared(res)
    {
#define MAX_PARALLEL_RECURSIVE_LEVEL 4

        #pragma omp single
        res = pi_r (h, 0, MAX_PARALLEL_RECURSIVE_LEVEL, 1, niters);
    }
    return res * h;
}


int main (int argc, char *argv[])
{
#define NITERS (100*1000*1000ULL)

    printf ("PI (w/%d iters) is %lf\n", NITERS, pi(NITERS));

    return 0;
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow