Megosztás a következőn keresztül:


OpenMP Directives

Az OpenMP API-ban használt irányelvekre mutató hivatkozásokat tartalmaz.

A Visual C++ a következő OpenMP-irányelveket támogatja.

Párhuzamos munkamegosztás esetén:

Directive Description
parallel Egy párhuzamos régiót definiál, amely egy kód, amelyet párhuzamosan több szál fog végrehajtani.
for A párhuzamos régión belüli hurokban for végzett munka szálak közötti megosztását eredményezi.
sections Azonosítja az összes szál között osztandó kódszakaszokat.
single Lehetővé teszi annak megadását, hogy a kód egy szakaszát egyetlen szálon kell végrehajtani, nem feltétlenül a fő szálon.

Főszál és szinkronizálás esetén:

Directive Description
master Azt határozza meg, hogy csak a főszál hajtsa végre a program egy szakaszát.
critical Azt adja meg, hogy a kód egyszerre csak egy szálon legyen végrehajtva.
barrier Szinkronizálja a csapat összes szálát; az összes szál megáll a sorompónál, amíg az összes szál végrehajtja az akadályt.
atomic Megadja, hogy a memóriahely atomilag frissül.
flush Azt adja meg, hogy minden szálnak ugyanaz a memórianézete legyen az összes megosztott objektumhoz.
ordered Azt határozza meg, hogy a párhuzamos for hurkokban lévő kódot szekvenciális hurokként kell végrehajtani.

Adatkörnyezet esetén:

Directive Description
threadprivate Azt adja meg, hogy egy változó egy szál magánjellegű-e.

atomi

Megadja, hogy egy memóriahely, amely atomilag frissül.

#pragma omp atomic
   expression

Parameters

expression
A lvalue értéket tartalmazó utasítás, amelynek a memóriahelyét egynél több írás ellen szeretné védeni.

Remarks

Az atomic irányelv nem támogat záradékokat.

További információ: 2.6.4 atomszerkezet.

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

Szinkronizálja a csapat összes szálát; az összes szál megáll a sorompónál, amíg az összes szál végrehajtja az akadályt.

#pragma omp barrier

Remarks

Az barrier irányelv nem támogat záradékokat.

További információ: 2.6.3 akadály irányelv.

Example

A használat barriermódjáról a főkiszolgálón tájékozódhat.

kritikus

Megadja, hogy a kód egyszerre csak egy szálon legyen végrehajtva.

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

Parameters

name
(Nem kötelező) A kritikus kód azonosítására szolgáló név. A nevet zárójelben kell megadni.

Remarks

Az critical irányelv nem támogat záradékokat.

További információ: 2.6.2 kritikus szerkezet.

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

igazít

Azt adja meg, hogy minden szálnak ugyanaz a memórianézete legyen az összes megosztott objektumhoz.

#pragma omp flush [(var)]

Parameters

var
(Nem kötelező) A szinkronizálni kívánt objektumokat képviselő változók vesszővel tagolt listája. Ha nincs megadva var , az összes memória ki lesz ürítve.

Remarks

Az flush irányelv nem támogat záradékokat.

További információ: 2.6.5 öblítési irányelv.

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

A párhuzamos régión belüli hurokban for végzett munka szálak közötti megosztását eredményezi.

#pragma omp [parallel] for [clauses]
   for_statement

Parameters

clauses
(Nem kötelező) Nulla vagy több záradék, lásd a Megjegyzések szakaszt .

for_statement
Egy for hurok. A nem definiált viselkedés akkor következik be, ha a for hurok felhasználói kódja módosítja az indexváltozót.

Remarks

Az for irányelv a következő záradékokat támogatja:

Ha parallel az is meg van adva, clauses akkor az irányelvek által parallelfor elfogadott bármely záradék lehet, kivéve nowait.

További információkért lásd a 2.4.1 konstrukciót.

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

Azt határozza meg, hogy csak a főszál hajtsa végre a program egy szakaszát.

#pragma omp master
{
   code_block
}

Remarks

Az master irányelv nem támogat záradékokat.

További információ: 2.6.1 főszerkezet.

Ha meg szeretné határozni, hogy a kód egy szakaszát egyetlen szálon kell végrehajtani, nem feltétlenül a fő szálon, használja inkább az egyetlen direktívát.

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

Azt határozza meg, hogy a párhuzamos for hurkokban lévő kódot szekvenciális hurokként kell végrehajtani.

#pragma omp ordered
   structured-block

Remarks

Az ordered irányelvnek egy záradékkal ellátott orderedfor vagy parallel for szerkezet dinamikus kiterjedésén belül kell lennie.

Az ordered irányelv nem támogat záradékokat.

További információ: 2.6.6 rendezett szerkezet.

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

Egy párhuzamos régiót definiál, amely egy kód, amelyet párhuzamosan több szál fog végrehajtani.

#pragma omp parallel [clauses]
{
   code_block
}

Parameters

clauses
(Nem kötelező) Nulla vagy több záradék, lásd a Megjegyzések szakaszt .

Remarks

Az parallel irányelv a következő záradékokat támogatja:

parallel a for és a szakaszokra vonatkozó irányelvekkel is használható.

További információ: 2.3 párhuzamos szerkezet.

Example

Az alábbi minta bemutatja, hogyan állíthatja be a szálak számát, és hogyan definiálhat párhuzamos régiót. A szálak száma alapértelmezés szerint megegyezik a gépen található logikai processzorok számával. Ha például egy olyan fizikai processzorral rendelkező géppel rendelkezik, amelyen engedélyezve van a hyperthreading, akkor két logikai processzorral és két szállal fog rendelkezni. A kimenet sorrendje különböző gépeken eltérő lehet.

// 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

Azonosítja az összes szál között osztandó kódszakaszokat.

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

Parameters

clauses
(Nem kötelező) Nulla vagy több záradék, lásd a Megjegyzések szakaszt .

Remarks

Az sections irányelv nulla vagy több section irányelvet tartalmazhat.

Az sections irányelv a következő záradékokat támogatja:

Ha parallel az is meg van adva, clauses akkor az irányelvek által parallelsections elfogadott bármely záradék lehet, kivéve nowait.

További információ: 2.4.2 szakaszok felépítése.

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

Lehetővé teszi annak megadását, hogy a kód egy szakaszát egyetlen szálon kell végrehajtani, nem feltétlenül a fő szálon.

#pragma omp single [clauses]
{
   code_block
}

Parameters

clauses
(Nem kötelező) Nulla vagy több záradék, lásd a Megjegyzések szakaszt .

Remarks

Az single irányelv a következő záradékokat támogatja:

További információ: 2.4.3 önálló szerkezet.

Ha meg szeretné adni, hogy a kód egy szakasza csak a fő szálon legyen végrehajtva, használja inkább a irányelvet.

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

Azt adja meg, hogy egy változó egy szál magánjellegű-e.

#pragma omp threadprivate(var)

Parameters

var
Vesszővel tagolt változók listája, amelyeket titkossá szeretne tenni egy szálon. a var-nak globális vagy névtér-hatókörű változónak vagy helyi statikus változónak kell lennie.

Remarks

Az threadprivate irányelv nem támogat záradékokat.

Az threadprivate irányelv a __declspec kulcsszót használó szálattribútumon alapul; azokra vonatkozó __declspec(thread) korlátozások vonatkoznakthreadprivate. Egy változó például threadprivate a folyamat során elindított bármely szálban létezni fog, nem csak azokban a szálakban, amelyek egy párhuzamos régió által létrehozott szálcsoport részei. Vegye figyelembe ezt a megvalósítási részletet; megfigyelheti, hogy a felhasználó által definiált threadprivate típus konstruktorai gyakrabban lesznek meghívva, mint a vártnál.

threadprivate A folyamat indításakor statikusan betöltött DLL-ekben azonban nem használhat threadprivate olyan DLL-t, amely a LoadLibrary használatával lesz betöltve, például a /DELAYLOAD (késleltetési terhelés importálása) szolgáltatással betöltött DLL-ekben, amelyek szintén használhatókLoadLibrary.

A threadprivatedestrukálható típusú változók nem garantáltan meghívják a destruktort. For example:

struct MyType
{
    ~MyType();
};

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

A felhasználók nem szabályozhatják, hogy a párhuzamos régiót alkotó szálak mikor fognak leállni. Ha ezek a szálak a folyamat kilépésekor léteznek, a szálak nem kapnak értesítést a folyamatkimenetről, és a destruktor nem lesz meghívva threaded_var egyetlen szálon sem, kivéve azt, amelyik kilép (itt az elsődleges szál). A kód tehát nem számít a változók megfelelő megsemmisítésére threadprivate .

További információ: 2.7.1 threadprivate direktíva.

Example

A használat threadprivatemintájáért lásd: privát.