Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
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 fő 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.