Aracılığıyla paylaş


OpenMP Yönergeleri

OpenMP API'sinde kullanılan yönergelerin bağlantılarını sağlar.

Visual C++ aşağıdaki OpenMP yönergelerini destekler.

Paralel iş paylaşımı için:

Directive Description
parallel Paralel olarak birden çok iş parçacığı tarafından yürütülecek kodu tanımlayan bir paralel bölge oluşturur.
for Paralel bölge içindeki bir for döngüsünde yapılan işin iş parçacıkları arasında bölünmesine sebep olur.
sections Tüm iş parçacıkları arasında bölünecek kod bölümlerini tanımlar.
single Kodun bir bölümünün ana iş parçacığında değil, tek bir iş parçacığında yürütülmesi gerektiğini belirtmenize olanak tanır.

Ana iş parçacığı ve senkronizasyon için:

Directive Description
master Yalnızca ana iş parçacığının programın bir bölümünü yürütmesi gerektiğini belirtir.
critical Kodun aynı anda yalnızca bir iş parçacığında yürütüldüğünü belirtir.
barrier Takımdaki tüm iş parçacıklarını senkronize eder; tüm iş parçacıkları bariyere gelene kadar bariyerde duraklatılır.
atomic Bir bellek konumunun atomik olarak güncelleştirileceğini belirtir.
flush Tüm iş parçacıklarının, tüm paylaşılan nesneler için aynı bellek görünümlerine sahip olmasını sağladığını belirtir.
ordered Paralelleştirilmiş for döngü altındaki kodun sıralı döngü gibi yürütülmesi gerektiğini belirtir.

Veri ortamı için:

Directive Description
threadprivate Bir değişkenin bir iş parçacığına özel olduğunu belirtir.

atomic

Atomik olarak güncelleştirilecek bir bellek konumunu belirtir.

#pragma omp atomic
   expression

Parameters

expression
Birden fazla yazma işlemine karşı korumak istediğiniz bellek konumunu içeren lvalue ifadesi.

Remarks

atomic yönergesi hiçbir koşulu desteklemez.

Daha fazla bilgi için bkz . 2.6.4 atomik yapısı.

Example

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

#define MAX 10

int main() {
   int count = 0;
   #pragma omp parallel num_threads(MAX)
   {
      #pragma omp atomic
      count++;
   }
   printf_s("Number of threads: %d\n", count);
}
Number of threads: 10

barrier

Ekipteki tüm iş parçacıklarını senkronize eder; tüm iş parçacıkları bariyerde durur ve tüm iş parçacıkları bariyeri gerçekleştirdiğinde devam eder.

#pragma omp barrier

Remarks

barrier yönergesi hiçbir koşulu desteklemez.

Daha fazla bilgi için bkz . 2.6.3 bariyer yönergesi.

Example

Bir barrier kullanımı örneği için bkz master.

critical

Kodun aynı anda yalnızca bir iş parçacığında yürütüldüğünü belirtir.

#pragma omp critical [(name)]
{
   code_block
}

Parameters

name
(İsteğe bağlı) Kritik kodu tanımlamak için bir ad. Ad parantez içine alınmalıdır.

Remarks

critical yönergesi hiçbir koşulu desteklemez.

Daha fazla bilgi için bkz . 2.6.2 kritik yapısı.

Example

// 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);
}
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
max = 29358

flush

Tüm iş parçacıklarının tüm paylaşılan nesneler için aynı bellek görünümüne sahip olduğunu belirtir.

#pragma omp flush [(var)]

Parameters

var
(İsteğe bağlı) Eşitlemek istediğiniz nesneleri temsil eden değişkenlerin virgülle ayrılmış listesi. var belirtilmezse, tüm bellek boşaltılır.

Remarks

flush yönergesi hiçbir koşulu desteklemez.

Daha fazla bilgi için bkz . 2.6.5 temizleme yönergesi.

Example

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

void read(int *data) {
   printf_s("read data\n");
   *data = 1;
}

void process(int *data) {
   printf_s("process data\n");
   (*data)++;
}

int main() {
   int data;
   int flag;

   flag = 0;

   #pragma omp parallel sections num_threads(2)
   {
      #pragma omp section
      {
         printf_s("Thread %d: ", omp_get_thread_num( ));
         read(&data);
         #pragma omp flush(data)
         flag = 1;
         #pragma omp flush(flag)
         // Do more work.
      }

      #pragma omp section
      {
         while (!flag) {
            #pragma omp flush(flag)
         }
         #pragma omp flush(data)

         printf_s("Thread %d: ", omp_get_thread_num( ));
         process(&data);
         printf_s("data = %d\n", data);
      }
   }
}
Thread 0: read data
Thread 1: process data
data = 2

for

Paralel bölge içindeki bir for döngüde yapılan işin iş parçacıkları arasında bölünmesini sağlar.

#pragma omp [parallel] for [clauses]
   for_statement

Parameters

clauses
Sıfır veya daha fazla yan tümce için bkz. Açıklamalar bölümü (İsteğe bağlı).

for_statement
Bir for döngü. Döngüdeki kullanıcı kodu dizin değişkenini for değiştirirse tanımsız davranış ortaya çıkar.

Remarks

"for yönergesi aşağıdaki yan cümleleri destekler:"

Eğer parallel de belirtilmişse, nowait dışındaki, parallel veya for yönergeleri tarafından kabul edilen herhangi bir yan tümce olabilir.

Daha fazla bilgi için 2.4.1'e bakın yapı.

Example

// omp_for.cpp
// compile with: /openmp
#include <stdio.h>
#include <math.h>
#include <omp.h>

#define NUM_THREADS 4
#define NUM_START 1
#define NUM_END 10

int main() {
   int i, nRet = 0, nSum = 0, nStart = NUM_START, nEnd = NUM_END;
   int nThreads = 0, nTmp = nStart + nEnd;
   unsigned uTmp = (unsigned((abs(nStart - nEnd) + 1)) *
                               unsigned(abs(nTmp))) / 2;
   int nSumCalc = uTmp;

   if (nTmp < 0)
      nSumCalc = -nSumCalc;

   omp_set_num_threads(NUM_THREADS);

   #pragma omp parallel default(none) private(i) shared(nSum, nThreads, nStart, nEnd)
   {
      #pragma omp master
      nThreads = omp_get_num_threads();

      #pragma omp for
      for (i=nStart; i<=nEnd; ++i) {
            #pragma omp atomic
            nSum += i;
      }
   }

   if  (nThreads == NUM_THREADS) {
      printf_s("%d OpenMP threads were used.\n", NUM_THREADS);
      nRet = 0;
   }
   else {
      printf_s("Expected %d OpenMP threads, but %d were used.\n",
               NUM_THREADS, nThreads);
      nRet = 1;
   }

   if (nSum != nSumCalc) {
      printf_s("The sum of %d through %d should be %d, "
               "but %d was reported!\n",
               NUM_START, NUM_END, nSumCalc, nSum);
      nRet = 1;
   }
   else
      printf_s("The sum of %d through %d is %d\n",
               NUM_START, NUM_END, nSum);
}
4 OpenMP threads were used.
The sum of 1 through 10 is 55

master

Yalnızca ana iş parçacığının programın bir bölümünü yürütmesi gerektiğini belirtir.

#pragma omp master
{
   code_block
}

Remarks

master yönergesi hiçbir koşulu desteklemez.

Daha fazla bilgi için bkz . 2.6.1 ana yapısı.

Kodun bir bölümünün ana iş parçacığı değil, tek bir iş parçacığında yürütülmesi gerektiğini belirtmek için bunun yerine tek yönergesini kullanın.

Example

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

int main( )
{
    int a[5], i;

    #pragma omp parallel
    {
        // Perform some computation.
        #pragma omp for
        for (i = 0; i < 5; i++)
            a[i] = i * i;

        // Print intermediate results.
        #pragma omp master
            for (i = 0; i < 5; i++)
                printf_s("a[%d] = %d\n", i, a[i]);

        // Wait.
        #pragma omp barrier

        // Continue with the computation.
        #pragma omp for
        for (i = 0; i < 5; i++)
            a[i] += i;
    }
}
a[0] = 0
a[1] = 1
a[2] = 4
a[3] = 9
a[4] = 16

ordered

Paralelleştirilmiş for döngü altındaki kodun sıralı döngü gibi yürütülmesi gerektiğini belirtir.

#pragma omp ordered
   structured-block

Remarks

yönergesi ordered , bir için veya parallel for yan tümcesi ile ordered yapısının dinamik kapsamı içinde olmalıdır.

ordered yönergesi hiçbir koşulu desteklemez.

Daha fazla bilgi için bkz . 2.6.6 sıralı yapısı.

Example

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

static float a[1000], b[1000], c[1000];

void test(int first, int last)
{
    #pragma omp for schedule(static) ordered
    for (int i = first; i <= last; ++i) {
        // Do something here.
        if (i % 2)
        {
            #pragma omp ordered
            printf_s("test() iteration %d\n", i);
        }
    }
}

void test2(int iter)
{
    #pragma omp ordered
    printf_s("test2() iteration %d\n", iter);
}

int main( )
{
    int i;
    #pragma omp parallel
    {
        test(1, 8);
        #pragma omp for ordered
        for (i = 0 ; i < 5 ; i++)
            test2(i);
    }
}
test() iteration 1
test() iteration 3
test() iteration 5
test() iteration 7
test2() iteration 0
test2() iteration 1
test2() iteration 2
test2() iteration 3
test2() iteration 4

parallel

Paralel olarak birden çok iş parçacığı tarafından yürütülecek kodu tanımlayan bir paralel bölge oluşturur.

#pragma omp parallel [clauses]
{
   code_block
}

Parameters

clauses
(İsteğe bağlı) Sıfır veya daha fazla cümle, Açıklamalar bölümüne bakın.

Remarks

parallel yönergesi aşağıdaki ifadeleri destekler.

parallel ayrıca için ve bölümleri yönergeleriyle de kullanılabilir.

Daha fazla bilgi için bkz . 2.3 paralel yapısı.

Example

Aşağıdaki örnek, iş parçacığı sayısını ayarlamayı ve paralel bir bölge tanımlamayı gösterir. İş parçacığı sayısı, varsayılan olarak makinedeki mantıksal işlemci sayısına eşittir. Örneğin, hiper iş parçacığı kullanımı etkinleştirilmiş bir fiziksel işlemciye sahip bir makineniz varsa, iki mantıksal işlemciye ve iki iş parçacığına sahip olur. Çıkışın sırası farklı makinelerde farklılık gösterebilir.

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

int main() {
   #pragma omp parallel num_threads(4)
   {
      int i = omp_get_thread_num();
      printf_s("Hello from thread %d\n", i);
   }
}
Hello from thread 0
Hello from thread 1
Hello from thread 2
Hello from thread 3

sections

Tüm iş parçacıkları arasında bölünecek kod bölümlerini tanımlar.

#pragma omp [parallel] sections [clauses]
{
   #pragma omp section
   {
      code_block
   }
}

Parameters

clauses
(İsteğe bağlı) Sıfır veya daha fazla yan tümce, Açıklamalar bölümüne bakın.

Remarks

yönergesi sections sıfır veya daha fazla section yönerge içerebilir.

sections yönergesi aşağıdaki koşulları destekler:

Eğer parallel de belirtilmişse, nowait dışındaki, parallel veya sections yönergeleri tarafından kabul edilen herhangi bir yan tümce olabilir.

Daha fazla bilgi için bkz . 2.4.2 bölüm yapısı.

Example

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

int main() {
    #pragma omp parallel sections num_threads(4)
    {
        printf_s("Hello from thread %d\n", omp_get_thread_num());
        #pragma omp section
        printf_s("Hello from thread %d\n", omp_get_thread_num());
    }
}
Hello from thread 0
Hello from thread 0

single

Kodun bir bölümünün ana iş parçacığında değil, tek bir iş parçacığında yürütülmesi gerektiğini belirtmenize olanak tanır.

#pragma omp single [clauses]
{
   code_block
}

Parameters

clauses
Sıfır veya daha fazla yan tümce için bkz. Açıklamalar bölümü (İsteğe bağlı).

Remarks

"single yönergesi aşağıdaki yan cümleleri destekler:"

Daha fazla bilgi için bkz . 2.4.3 tek yapı.

Bir kod bölümünün yalnızca ana iş parçacığında yürütülmesi gerektiğini belirtmek için bunun yerine ana yönergesini kullanın.

Example

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

int main() {
   #pragma omp parallel num_threads(2)
   {
      #pragma omp single
      // Only a single thread can read the input.
      printf_s("read input\n");

      // Multiple threads in the team compute the results.
      printf_s("compute results\n");

      #pragma omp single
      // Only a single thread can write the output.
      printf_s("write output\n");
    }
}
read input
compute results
compute results
write output

threadprivate

Bir değişkenin bir iş parçacığına özel olduğunu belirtir.

#pragma omp threadprivate(var)

Parameters

var
İş parçacığına özel yapmak istediğiniz değişkenlerin virgülle ayrılmış listesi. var , genel veya ad alanı kapsamlı bir değişken veya yerel statik değişken olmalıdır.

Remarks

threadprivate yönergesi hiçbir koşulu desteklemez.

Yönerge threadprivate, __declspec anahtar sözcüğünü kullanan iş parçacığı özniteliğini temel alır; __declspec(thread) üzerindeki sınırlar threadprivate için geçerlidir. Örneğin, yalnızca threadprivate paralel bölge tarafından oluşturulan bir iş parçacığı ekibinin parçası olan iş parçacıklarında değil, işlemde başlatılan herhangi bir iş parçacığında bir değişken bulunur. Bu uygulama ayrıntılarına dikkat edin; kullanıcı tanımlı bir threadprivate tür için yapıcıların beklenenden daha sık çağrıldığını fark edebilirsiniz.

İşlem başlangıcında statik olarak yüklenen bir DLL'de threadprivate kullanabilirsiniz, ancak threadprivate'yı kullanamazsınız. Özellikle, LoadLibrary aracılığıyla yüklenecek DLL'lerde, örneğin /DELAYLOAD (gecikmeli yük içe aktarma) ile yüklenen DLL'lerde, bu durum geçerlidir, çünkü bu da LoadLibrary kullanır.

Yok edilebilir türden bir değişkenin destrüktörünün çağrıldığı garanti edilemez. Örneğin:

struct MyType
{
    ~MyType();
};

MyType threaded_var;
#pragma omp threadprivate(threaded_var)
int main()
{
    #pragma omp parallel
    {}
}

Kullanıcıların paralel bölgeyi oluşturan iş parçacıklarının ne zaman sonlandırılacağı konusunda hiçbir denetimi yoktur. İşlemin sonlandığı anda bu iş parçacıkları mevcutsa, iş parçacıkları işlem çıkışı hakkında bilgilendirilmez ve threaded_var yıkıcısı, çıkışı gerçekleştiren iş parçacığı (burada birincil iş parçacığı) hariç diğer iş parçacıklarında çağrılmaz. Bu nedenle kod, değişkenlerin doğru şekilde yok edilmesine threadprivate bağlı olmamalıdır.

Daha fazla bilgi için bkz . 2.7.1 threadprivate yönergesi.

Example

threadprivate kullanımı için örneğe bakın, bkz özel.