Delen via


OpenMP Directives

Bevat koppelingen naar instructies die worden gebruikt in de OpenMP-API.

Visual C++ ondersteunt de volgende OpenMP-instructies.

Voor parallel delen van werk:

Directive Description
parallel Hiermee definieert u een parallelle regio. Dit is code die parallel door meerdere threads wordt uitgevoerd.
for Zorgt ervoor dat het werk dat in een for lus binnen een parallelle regio wordt uitgevoerd, wordt verdeeld over threads.
sections Identificeert codesecties die moeten worden verdeeld over alle threads.
single Hiermee kunt u opgeven dat een codesectie moet worden uitgevoerd op één thread, niet noodzakelijkerwijs de hoofdthread.

Voor hoofdthread en synchronisatie:

Directive Description
master Hiermee geeft u op dat alleen de hoofdthread een sectie van het programma moet uitvoeren.
critical Hiermee geeft u op dat code slechts op één thread tegelijk wordt uitgevoerd.
barrier Synchroniseert alle threads in een team; alle threads pauzeren bij de barrière, totdat alle threads de barrière uitvoeren.
atomic Hiermee geeft u op dat een geheugenlocatie atomisch wordt bijgewerkt.
flush Hiermee geeft u op dat alle threads dezelfde weergave van het geheugen hebben voor alle gedeelde objecten.
ordered Hiermee geeft u op dat code onder een parallelle for lus moet worden uitgevoerd als een sequentiële lus.

Voor de gegevensomgeving:

Directive Description
threadprivate Hiermee geeft u op dat een variabele privé is voor een thread.

atomic

Hiermee geeft u op dat een geheugenlocatie die atomisch wordt bijgewerkt.

#pragma omp atomic
   expression

Parameters

expression
De instructie met de lvalue, waarvan u de geheugenlocatie wilt beveiligen tegen meer dan één schrijfbewerking.

Remarks

De atomic richtlijn ondersteunt geen bepalingen.

Zie 2.6.4 atomic construct voor meer informatie.

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

Synchroniseert alle threads in een team; alle threads pauzeren bij de barrière, totdat alle threads de barrière uitvoeren.

#pragma omp barrier

Remarks

De barrier richtlijn ondersteunt geen bepalingen.

Zie 2.6.3-barrièrerichtlijn voor meer informatie.

Example

Zie master voor een voorbeeld van hoe u deze kunt gebruikenbarrier.

critical

Hiermee geeft u op dat code slechts op één thread tegelijk wordt uitgevoerd.

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

Parameters

name
(Optioneel) Een naam om de kritieke code te identificeren. De naam moet tussen haakjes staan.

Remarks

De critical richtlijn ondersteunt geen bepalingen.

Zie 2.6.2 kritieke constructie voor meer informatie.

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

Hiermee geeft u op dat alle threads dezelfde weergave van het geheugen hebben voor alle gedeelde objecten.

#pragma omp flush [(var)]

Parameters

var
(Optioneel) Een door komma's gescheiden lijst met variabelen die objecten vertegenwoordigen die u wilt synchroniseren. Als var niet is opgegeven, wordt alle geheugen leeggemaakt.

Remarks

De flush richtlijn ondersteunt geen bepalingen.

Zie 2.6.5 flush directive voor meer informatie.

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

Zorgt ervoor dat het werk dat in een for lus binnen een parallelle regio wordt uitgevoerd, wordt verdeeld over threads.

#pragma omp [parallel] for [clauses]
   for_statement

Parameters

clauses
(Optioneel) Nul of meer componenten, zie de sectie Opmerkingen .

for_statement
Een for lus. Niet-gedefinieerd gedrag resulteert als gebruikerscode in de for lus de indexvariabele wijzigt.

Remarks

De for richtlijn ondersteunt de volgende bepalingen:

Als parallel dit ook is opgegeven, clauses kan elke clausule worden geaccepteerd door de parallel of for richtlijnen, met uitzondering nowaitvan .

Zie 2.4.1 voor meer informatie voor constructie.

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

Hiermee geeft u op dat alleen de hoofdthread een sectie van het programma moet uitvoeren.

#pragma omp master
{
   code_block
}

Remarks

De master richtlijn ondersteunt geen bepalingen.

Zie 2.6.1-hoofdconstructie voor meer informatie.

Als u wilt opgeven dat een codesectie moet worden uitgevoerd op één thread, niet noodzakelijkerwijs de hoofdthread, gebruikt u in plaats daarvan de één richtlijn.

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

Hiermee geeft u op dat code onder een parallelle for lus moet worden uitgevoerd als een sequentiële lus.

#pragma omp ordered
   structured-block

Remarks

De ordered richtlijn moet binnen de dynamische omvang van een voor - of parallel for constructie met een ordered component vallen.

De ordered richtlijn ondersteunt geen bepalingen.

Zie 2.6.6 geordende constructie voor meer informatie.

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

Hiermee definieert u een parallelle regio. Dit is code die parallel door meerdere threads wordt uitgevoerd.

#pragma omp parallel [clauses]
{
   code_block
}

Parameters

clauses
(Optioneel) Nul of meer componenten, zie de sectie Opmerkingen .

Remarks

De parallel richtlijn ondersteunt de volgende bepalingen:

parallel kan ook worden gebruikt met de richtlijnen voor en secties .

Zie 2.3 parallel construct voor meer informatie.

Example

In het volgende voorbeeld ziet u hoe u het aantal threads instelt en een parallelle regio definieert. Het aantal threads is standaard gelijk aan het aantal logische processors op de computer. Als u bijvoorbeeld een machine met één fysieke processor hebt waarvoor hyperthreading is ingeschakeld, zijn er twee logische processors en twee threads. De uitvoervolgorde kan variëren op verschillende computers.

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

Identificeert codesecties die moeten worden verdeeld over alle threads.

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

Parameters

clauses
(Optioneel) Nul of meer componenten, zie de sectie Opmerkingen .

Remarks

De sections richtlijn kan nul of meer section instructies bevatten.

De sections richtlijn ondersteunt de volgende bepalingen:

Als parallel dit ook is opgegeven, clauses kan elke clausule worden geaccepteerd door de parallel of sections richtlijnen, met uitzondering nowaitvan .

Zie de secties construct 2.4.2 voor meer informatie.

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

Hiermee kunt u opgeven dat een codesectie moet worden uitgevoerd op één thread, niet noodzakelijkerwijs de hoofdthread.

#pragma omp single [clauses]
{
   code_block
}

Parameters

clauses
(Optioneel) Nul of meer componenten, zie de sectie Opmerkingen .

Remarks

De single richtlijn ondersteunt de volgende bepalingen:

Zie 2.4.3 single construct voor meer informatie.

Als u wilt opgeven dat een codesectie alleen moet worden uitgevoerd op de hoofdthread, gebruikt u in plaats daarvan de hoofdrichtlijn .

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

Hiermee geeft u op dat een variabele privé is voor een thread.

#pragma omp threadprivate(var)

Parameters

var
Een door komma's gescheiden lijst met variabelen die u privé wilt maken voor een thread. var moet een globale- of naamruimtevariabele of een lokale statische variabele zijn.

Remarks

De threadprivate richtlijn ondersteunt geen bepalingen.

De threadprivate richtlijn is gebaseerd op het threadkenmerk met behulp van het __declspec trefwoord; limieten voor __declspec(thread) van toepassing op threadprivate. Er bestaat bijvoorbeeld een threadprivate variabele in een thread die in het proces is gestart, niet alleen de threads die deel uitmaken van een threadteam dat is voortgebracht door een parallelle regio. Houd rekening met deze implementatiedetails; U ziet mogelijk dat constructors voor een door de threadprivate gebruiker gedefinieerd type vaker worden aangeroepen dan verwacht.

U kunt threadprivate in een DLL die statisch wordt geladen bij het opstarten van het proces, maar u kunt niet gebruiken threadprivate in een DLL die wordt geladen via LoadLibrary , zoals DLL's die zijn geladen met /DELAYLOAD (vertragingsimport) die ook worden gebruikt LoadLibrary.

Een threadprivate variabele van een afbreekbaar type is niet gegarandeerd dat destructor wordt aangeroepen. For example:

struct MyType
{
    ~MyType();
};

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

Gebruikers hebben geen controle over wanneer de threads die de parallelle regio vormen, worden beëindigd. Als deze threads bestaan wanneer het proces wordt afgesloten, worden de threads niet op de hoogte gesteld van het afsluiten van het proces en wordt de destructor niet aangeroepen threaded_var op een thread, behalve de thread die wordt afgesloten (hier de primaire thread). Code mag dus niet rekenen op de juiste vernietiging van threadprivate variabelen.

Zie de threadprivate-instructie 2.7.1 voor meer informatie.

Example

Zie privé voor een voorbeeld van het gebruikthreadprivate.