OpenMP-Klauseln
Stellt Links zu Klauseln bereit, die in der OpenMP-API verwendet werden.
Visual C++ unterstützt die folgenden OpenMP-Klauseln.
Für allgemeine Attribute:
Klausel | Beschreibung |
---|---|
if | Gibt an, ob eine Schleife parallel oder serial ausgeführt werden soll. |
num_threads | Legt die Anzahl der Threads in einem Threadteam fest. |
angeordnet | Erforderlich für eine parallele Anweisung , wenn eine geordnete Direktive in der Schleife verwendet werden soll. |
schedule | Gilt für die Direktive . |
nowait | Überschreibt die in einer Direktive implizite Barriere. |
Für Datenfreigabeattribute:
Klausel | Beschreibung |
---|---|
private | Gibt an, dass jeder Thread über eine eigene Instanz einer Variablen verfügen soll. |
firstprivate | Gibt an, dass jeder Thread eine eigene Instanz einer Variablen haben soll und dass die Variable mit dem Wert der Variablen initialisiert werden soll, da sie vor dem parallelen Konstrukt vorhanden ist. |
lastprivate | Gibt an, dass die Version des eingeschlossenen Kontexts der Variablen auf die private Version des Threads festgelegt wird, für die der letzte Iteration (for-loop-Konstrukt) oder der letzte Abschnitt (#pragma Abschnitte) ausgeführt wird. |
geteilt | Gibt an, dass eine oder mehrere Variablen für alle Threads freigegeben werden sollen. |
default | Gibt das Verhalten von nicht bereichsierten Variablen in einem parallelen Bereich an. |
reduction | Gibt an, dass mindestens eine Variable, die für jeden Thread privat ist, das Thema eines Reduzierungsvorgangs am Ende des parallelen Bereichs ist. |
copyin | Ermöglicht Threads den Zugriff auf den Wert des Hauptthreads für eine Threadprivate-Variable . |
copyprivate | Gibt an, dass eine oder mehrere Variablen für alle Threads freigegeben werden sollen. |
copyin
Ermöglicht Threads den Zugriff auf den Wert des Hauptthreads für eine Threadprivate-Variable .
copyin(var)
Parameter
var
Die threadprivate
Variable, die mit dem Wert der Variablen im Hauptthread initialisiert wird, wie sie vor dem parallelen Konstrukt vorhanden ist.
Hinweise
copyin
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.7.2.7 copyin.
Beispiel
Ein Beispiel für die Verwendung copyin
finden Sie unter threadprivate .
copyprivate
Gibt an, dass eine oder mehrere Variablen für alle Threads freigegeben werden sollen.
copyprivate(var)
Parameter
var
Mindestens eine Variable, die freigegeben werden soll. Wenn mehrere Variablen angegeben werden, trennen Sie Variablennamen mit einem Komma.
Hinweise
copyprivate
gilt für die einheitliche Richtlinie.
Weitere Informationen finden Sie unter 2.7.2.8 copyprivate.
Beispiel
// omp_copyprivate.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
float x, y, fGlobal = 1.0;
#pragma omp threadprivate(x, y)
float get_float() {
fGlobal += 0.001;
return fGlobal;
}
void use_float(float f, int t) {
printf_s("Value = %f, thread = %d\n", f, t);
}
void CopyPrivate(float a, float b) {
#pragma omp single copyprivate(a, b, x, y)
{
a = get_float();
b = get_float();
x = get_float();
y = get_float();
}
use_float(a, omp_get_thread_num());
use_float(b, omp_get_thread_num());
use_float(x, omp_get_thread_num());
use_float(y, omp_get_thread_num());
}
int main() {
float a = 9.99, b = 123.456;
printf_s("call CopyPrivate from a single thread\n");
CopyPrivate(9.99, 123.456);
printf_s("call CopyPrivate from a parallel region\n");
#pragma omp parallel
{
CopyPrivate(a, b);
}
}
call CopyPrivate from a single thread
Value = 1.001000, thread = 0
Value = 1.002000, thread = 0
Value = 1.003000, thread = 0
Value = 1.004000, thread = 0
call CopyPrivate from a parallel region
Value = 1.005000, thread = 0
Value = 1.005000, thread = 1
Value = 1.006000, thread = 0
Value = 1.006000, thread = 1
Value = 1.007000, thread = 0
Value = 1.007000, thread = 1
Value = 1.008000, thread = 0
Value = 1.008000, thread = 1
default
Gibt das Verhalten von nicht bereichsierten Variablen in einem parallelen Bereich an.
default(shared | none)
Hinweise
shared
, was in Kraft ist, wenn die default
Klausel nicht angegeben ist, bedeutet, dass jede Variable in einem parallelen Bereich so behandelt wird, als ob sie mit der freigegebenen Klausel angegeben wurde. none
bedeutet, dass alle variablen, die in einem parallelen Bereich verwendet werden, die nicht auf den Bereich private, freigegebene, reduktion, firstprivate oder lastprivate-Klausel festgelegt sind, einen Compilerfehler verursachen.
default
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.7.2.5 Standard.
Beispiel
Ein Beispiel für die Verwendung finden Sie unter "Privat " default
.
firstprivate
Gibt an, dass jeder Thread eine eigene Instanz einer Variablen haben soll und dass die Variable mit dem Wert der Variablen initialisiert werden soll, da sie vor dem parallelen Konstrukt vorhanden ist.
firstprivate(var)
Parameter
var
Die Variable, die Instanzen in jedem Thread enthalten soll und die mit dem Wert der Variablen initialisiert werden, da sie vor dem parallelen Konstrukt vorhanden ist. Wenn mehrere Variablen angegeben werden, trennen Sie Variablennamen mit einem Komma.
Hinweise
firstprivate
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.7.2.2 firstprivate.
Beispiel
Ein Beispiel für die Verwendung firstprivate
finden Sie im Beispiel in "Privat".
if (OpenMP)
Gibt an, ob eine Schleife parallel oder serial ausgeführt werden soll.
if(expression)
Parameter
expression
Ein integraler Ausdruck, der, wenn er als wahr ausgewertet wird (nonzero), bewirkt, dass der Code im parallelen Bereich parallel ausgeführt wird. Wenn der Ausdruck auf "false" (Null) ausgewertet wird, wird der parallele Bereich in der seriellen Ausführung (durch einen einzelnen Thread) ausgeführt.
Hinweise
if
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.3 paralleles Konstrukt.
Beispiel
// omp_if.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
void test(int val)
{
#pragma omp parallel if (val)
if (omp_in_parallel())
{
#pragma omp single
printf_s("val = %d, parallelized with %d threads\n",
val, omp_get_num_threads());
}
else
{
printf_s("val = %d, serialized\n", val);
}
}
int main( )
{
omp_set_num_threads(2);
test(0);
test(2);
}
val = 0, serialized
val = 2, parallelized with 2 threads
lastprivate
Gibt an, dass die Version des eingeschlossenen Kontexts der Variablen auf die private Version des Threads festgelegt wird, für die der letzte Iteration (for-loop-Konstrukt) oder der letzte Abschnitt (#pragma Abschnitte) ausgeführt wird.
lastprivate(var)
Parameter
var
Die Variable, die auf die private Version des Threads festgelegt ist, führt die endgültige Iteration (For-Loop-Konstrukt) oder den letzten Abschnitt (#pragma Abschnitte) aus.
Hinweise
lastprivate
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.7.2.3 lastprivate.
Beispiel
Ein Beispiel für die Verwendung lastprivate
von Klauseln finden Sie im Zeitplan.
nowait
Überschreibt die in einer Direktive implizite Barriere.
nowait
Hinweise
nowait
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.4.1 für Konstrukte, 2.4.2-Abschnitte und 2.4.3 einzelnes Konstrukt.
Beispiel
// omp_nowait.cpp
// compile with: /openmp /c
#include <stdio.h>
#define SIZE 5
void test(int *a, int *b, int *c, int size)
{
int i;
#pragma omp parallel
{
#pragma omp for nowait
for (i = 0; i < size; i++)
b[i] = a[i] * a[i];
#pragma omp for nowait
for (i = 0; i < size; i++)
c[i] = a[i]/2;
}
}
int main( )
{
int a[SIZE], b[SIZE], c[SIZE];
int i;
for (i=0; i<SIZE; i++)
a[i] = i;
test(a,b,c, SIZE);
for (i=0; i<SIZE; i++)
printf_s("%d, %d, %d\n", a[i], b[i], c[i]);
}
0, 0, 0
1, 1, 0
2, 4, 1
3, 9, 1
4, 16, 2
num_threads
Legt die Anzahl der Threads in einem Threadteam fest.
num_threads(num)
Parameter
num
Die Anzahl der Threads
Hinweise
Die num_threads
Klausel weist die gleiche Funktionalität wie die omp_set_num_threads-Funktion auf.
num_threads
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.3 paralleles Konstrukt.
Beispiel
Ein Beispiel für die Verwendung num_threads
von Klauseln finden Sie parallel.
geordnete
Erforderlich für eine parallele Anweisung , wenn eine geordnete Direktive in der Schleife verwendet werden soll.
ordered
Hinweise
ordered
gilt für die Richtlinie .
Weitere Informationen finden Sie unter 2.4.1 für das Konstrukt.
Beispiel
Ein Beispiel für die Verwendungsklausel ordered
finden Sie unter "Sortiert".
private
Gibt an, dass jeder Thread über eine eigene Instanz einer Variablen verfügen soll.
private(var)
Parameter
var
Die Variable, die Instanzen in jedem Thread enthalten soll.
Hinweise
private
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.7.2.1 privat.
Beispiel
// openmp_private.c
// compile with: /openmp
#include <windows.h>
#include <assert.h>
#include <stdio.h>
#include <omp.h>
#define NUM_THREADS 4
#define SLEEP_THREAD 1
#define NUM_LOOPS 2
enum Types {
ThreadPrivate,
Private,
FirstPrivate,
LastPrivate,
Shared,
MAX_TYPES
};
int nSave[NUM_THREADS][MAX_TYPES][NUM_LOOPS] = {{0}};
int nThreadPrivate;
#pragma omp threadprivate(nThreadPrivate)
#pragma warning(disable:4700)
int main() {
int nPrivate = NUM_THREADS;
int nFirstPrivate = NUM_THREADS;
int nLastPrivate = NUM_THREADS;
int nShared = NUM_THREADS;
int nRet = 0;
int i;
int j;
int nLoop = 0;
nThreadPrivate = NUM_THREADS;
printf_s("These are the variables before entry "
"into the parallel region.\n");
printf_s("nThreadPrivate = %d\n", nThreadPrivate);
printf_s(" nPrivate = %d\n", nPrivate);
printf_s(" nFirstPrivate = %d\n", nFirstPrivate);
printf_s(" nLastPrivate = %d\n", nLastPrivate);
printf_s(" nShared = %d\n\n", nShared);
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel copyin(nThreadPrivate) private(nPrivate) shared(nShared) firstprivate(nFirstPrivate)
{
#pragma omp for schedule(static) lastprivate(nLastPrivate)
for (i = 0 ; i < NUM_THREADS ; ++i) {
for (j = 0 ; j < NUM_LOOPS ; ++j) {
int nThread = omp_get_thread_num();
assert(nThread < NUM_THREADS);
if (nThread == SLEEP_THREAD)
Sleep(100);
nSave[nThread][ThreadPrivate][j] = nThreadPrivate;
nSave[nThread][Private][j] = nPrivate;
nSave[nThread][Shared][j] = nShared;
nSave[nThread][FirstPrivate][j] = nFirstPrivate;
nSave[nThread][LastPrivate][j] = nLastPrivate;
nThreadPrivate = nThread;
nPrivate = nThread;
nShared = nThread;
nLastPrivate = nThread;
--nFirstPrivate;
}
}
}
for (i = 0 ; i < NUM_LOOPS ; ++i) {
for (j = 0 ; j < NUM_THREADS ; ++j) {
printf_s("These are the variables at entry of "
"loop %d of thread %d.\n", i + 1, j);
printf_s("nThreadPrivate = %d\n",
nSave[j][ThreadPrivate][i]);
printf_s(" nPrivate = %d\n",
nSave[j][Private][i]);
printf_s(" nFirstPrivate = %d\n",
nSave[j][FirstPrivate][i]);
printf_s(" nLastPrivate = %d\n",
nSave[j][LastPrivate][i]);
printf_s(" nShared = %d\n\n",
nSave[j][Shared][i]);
}
}
printf_s("These are the variables after exit from "
"the parallel region.\n");
printf_s("nThreadPrivate = %d (The last value in the "
"main thread)\n", nThreadPrivate);
printf_s(" nPrivate = %d (The value prior to "
"entering parallel region)\n", nPrivate);
printf_s(" nFirstPrivate = %d (The value prior to "
"entering parallel region)\n", nFirstPrivate);
printf_s(" nLastPrivate = %d (The value from the "
"last iteration of the loop)\n", nLastPrivate);
printf_s(" nShared = %d (The value assigned, "
"from the delayed thread, %d)\n\n",
nShared, SLEEP_THREAD);
}
These are the variables before entry into the parallel region.
nThreadPrivate = 4
nPrivate = 4
nFirstPrivate = 4
nLastPrivate = 4
nShared = 4
These are the variables at entry of loop 1 of thread 0.
nThreadPrivate = 4
nPrivate = 1310720
nFirstPrivate = 4
nLastPrivate = 1245104
nShared = 3
These are the variables at entry of loop 1 of thread 1.
nThreadPrivate = 4
nPrivate = 4488
nFirstPrivate = 4
nLastPrivate = 19748
nShared = 0
These are the variables at entry of loop 1 of thread 2.
nThreadPrivate = 4
nPrivate = -132514848
nFirstPrivate = 4
nLastPrivate = -513199792
nShared = 4
These are the variables at entry of loop 1 of thread 3.
nThreadPrivate = 4
nPrivate = 1206
nFirstPrivate = 4
nLastPrivate = 1204
nShared = 2
These are the variables at entry of loop 2 of thread 0.
nThreadPrivate = 0
nPrivate = 0
nFirstPrivate = 3
nLastPrivate = 0
nShared = 0
These are the variables at entry of loop 2 of thread 1.
nThreadPrivate = 1
nPrivate = 1
nFirstPrivate = 3
nLastPrivate = 1
nShared = 1
These are the variables at entry of loop 2 of thread 2.
nThreadPrivate = 2
nPrivate = 2
nFirstPrivate = 3
nLastPrivate = 2
nShared = 2
These are the variables at entry of loop 2 of thread 3.
nThreadPrivate = 3
nPrivate = 3
nFirstPrivate = 3
nLastPrivate = 3
nShared = 3
These are the variables after exit from the parallel region.
nThreadPrivate = 0 (The last value in the main thread)
nPrivate = 4 (The value prior to entering parallel region)
nFirstPrivate = 4 (The value prior to entering parallel region)
nLastPrivate = 3 (The value from the last iteration of the loop)
nShared = 1 (The value assigned, from the delayed thread, 1)
reduction
Gibt an, dass mindestens eine Variable, die für jeden Thread privat ist, das Thema eines Reduzierungsvorgangs am Ende des parallelen Bereichs ist.
reduction(operation:var)
Parameter
operation
Der Operator für den Vorgang, der für die Variablen var am Ende des parallelen Bereichs ausgeführt werden soll.
var
Eine oder mehrere Variablen, für die skalare Reduzierung ausgeführt werden soll. Wenn mehrere Variablen angegeben werden, trennen Sie Variablennamen mit einem Komma.
Hinweise
reduction
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.7.2.6 Reduzierung.
Beispiel
// omp_reduction.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>
#define NUM_THREADS 4
#define SUM_START 1
#define SUM_END 10
#define FUNC_RETS {1, 1, 1, 1, 1}
int bRets[5] = FUNC_RETS;
int nSumCalc = ((SUM_START + SUM_END) * (SUM_END - SUM_START + 1)) / 2;
int func1( ) {return bRets[0];}
int func2( ) {return bRets[1];}
int func3( ) {return bRets[2];}
int func4( ) {return bRets[3];}
int func5( ) {return bRets[4];}
int main( )
{
int nRet = 0,
nCount = 0,
nSum = 0,
i,
bSucceed = 1;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel reduction(+ : nCount)
{
nCount += 1;
#pragma omp for reduction(+ : nSum)
for (i = SUM_START ; i <= SUM_END ; ++i)
nSum += i;
#pragma omp sections reduction(&& : bSucceed)
{
#pragma omp section
{
bSucceed = bSucceed && func1( );
}
#pragma omp section
{
bSucceed = bSucceed && func2( );
}
#pragma omp section
{
bSucceed = bSucceed && func3( );
}
#pragma omp section
{
bSucceed = bSucceed && func4( );
}
#pragma omp section
{
bSucceed = bSucceed && func5( );
}
}
}
printf_s("The parallel section was executed %d times "
"in parallel.\n", nCount);
printf_s("The sum of the consecutive integers from "
"%d to %d, is %d\n", 1, 10, nSum);
if (bSucceed)
printf_s("All of the functions, func1 through "
"func5 succeeded!\n");
else
printf_s("One or more of the functions, func1 "
"through func5 failed!\n");
if (nCount != NUM_THREADS)
{
printf_s("ERROR: For %d threads, %d were counted!\n",
NUM_THREADS, nCount);
nRet |= 0x1;
}
if (nSum != nSumCalc)
{
printf_s("ERROR: The sum of %d through %d should be %d, "
"but %d was reported!\n",
SUM_START, SUM_END, nSumCalc, nSum);
nRet |= 0x10;
}
if (bSucceed != (bRets[0] && bRets[1] &&
bRets[2] && bRets[3] && bRets[4]))
{
printf_s("ERROR: The sum of %d through %d should be %d, "
"but %d was reported!\n",
SUM_START, SUM_END, nSumCalc, nSum);
nRet |= 0x100;
}
}
The parallel section was executed 4 times in parallel.
The sum of the consecutive integers from 1 to 10, is 55
All of the functions, func1 through func5 succeeded!
schedule
Gilt für die Direktive .
schedule(type[,size])
Parameter
type
Die Art der Planung, entweder dynamic
, , guided
, runtime
oder static
.
size
(Optional) Gibt die Größe der Iterationen an. Die Größe muss eine ganze Zahl sein. Ungültig, wenn der Typ ist runtime
.
Hinweise
Weitere Informationen finden Sie unter 2.4.1 für das Konstrukt.
Beispiel
// omp_schedule.cpp
// compile with: /openmp
#include <windows.h>
#include <stdio.h>
#include <omp.h>
#define NUM_THREADS 4
#define STATIC_CHUNK 5
#define DYNAMIC_CHUNK 5
#define NUM_LOOPS 20
#define SLEEP_EVERY_N 3
int main( )
{
int nStatic1[NUM_LOOPS],
nStaticN[NUM_LOOPS];
int nDynamic1[NUM_LOOPS],
nDynamicN[NUM_LOOPS];
int nGuided[NUM_LOOPS];
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
#pragma omp for schedule(static, 1)
for (int i = 0 ; i < NUM_LOOPS ; ++i)
{
if ((i % SLEEP_EVERY_N) == 0)
Sleep(0);
nStatic1[i] = omp_get_thread_num( );
}
#pragma omp for schedule(static, STATIC_CHUNK)
for (int i = 0 ; i < NUM_LOOPS ; ++i)
{
if ((i % SLEEP_EVERY_N) == 0)
Sleep(0);
nStaticN[i] = omp_get_thread_num( );
}
#pragma omp for schedule(dynamic, 1)
for (int i = 0 ; i < NUM_LOOPS ; ++i)
{
if ((i % SLEEP_EVERY_N) == 0)
Sleep(0);
nDynamic1[i] = omp_get_thread_num( );
}
#pragma omp for schedule(dynamic, DYNAMIC_CHUNK)
for (int i = 0 ; i < NUM_LOOPS ; ++i)
{
if ((i % SLEEP_EVERY_N) == 0)
Sleep(0);
nDynamicN[i] = omp_get_thread_num( );
}
#pragma omp for schedule(guided)
for (int i = 0 ; i < NUM_LOOPS ; ++i)
{
if ((i % SLEEP_EVERY_N) == 0)
Sleep(0);
nGuided[i] = omp_get_thread_num( );
}
}
printf_s("------------------------------------------------\n");
printf_s("| static | static | dynamic | dynamic | guided |\n");
printf_s("| 1 | %d | 1 | %d | |\n",
STATIC_CHUNK, DYNAMIC_CHUNK);
printf_s("------------------------------------------------\n");
for (int i=0; i<NUM_LOOPS; ++i)
{
printf_s("| %d | %d | %d | %d |"
" %d |\n",
nStatic1[i], nStaticN[i],
nDynamic1[i], nDynamicN[i], nGuided[i]);
}
printf_s("------------------------------------------------\n");
}
------------------------------------------------
| static | static | dynamic | dynamic | guided |
| 1 | 5 | 1 | 5 | |
------------------------------------------------
| 0 | 0 | 0 | 2 | 1 |
| 1 | 0 | 3 | 2 | 1 |
| 2 | 0 | 3 | 2 | 1 |
| 3 | 0 | 3 | 2 | 1 |
| 0 | 0 | 2 | 2 | 1 |
| 1 | 1 | 2 | 3 | 3 |
| 2 | 1 | 2 | 3 | 3 |
| 3 | 1 | 0 | 3 | 3 |
| 0 | 1 | 0 | 3 | 3 |
| 1 | 1 | 0 | 3 | 2 |
| 2 | 2 | 1 | 0 | 2 |
| 3 | 2 | 1 | 0 | 2 |
| 0 | 2 | 1 | 0 | 3 |
| 1 | 2 | 2 | 0 | 3 |
| 2 | 2 | 2 | 0 | 0 |
| 3 | 3 | 2 | 1 | 0 |
| 0 | 3 | 3 | 1 | 1 |
| 1 | 3 | 3 | 1 | 1 |
| 2 | 3 | 3 | 1 | 1 |
| 3 | 3 | 0 | 1 | 3 |
------------------------------------------------
shared
Gibt an, dass eine oder mehrere Variablen für alle Threads freigegeben werden sollen.
shared(var)
Parameter
var
Mindestens eine Variable, die freigegeben werden soll. Wenn mehrere Variablen angegeben werden, trennen Sie Variablennamen mit einem Komma.
Hinweise
Eine weitere Möglichkeit zum Freigeben von Variablen zwischen Threads ist die CopyPrivate-Klausel .
shared
gilt für die folgenden Richtlinien:
Weitere Informationen finden Sie unter 2.7.2.4 freigegeben.
Beispiel
Ein Beispiel für die Verwendung finden Sie unter "Privat " shared
.