1. Úvod
Tento dokument určuje kolekci direktiv kompilátoru, funkcí knihovny a proměnných prostředí, které můžete použít k určení paralelismu sdílené paměti v programech C a C++. Funkce popsané v tomto dokumentu se souhrnně označují jako rozhraní API (Application Program Interface) OpenMP C/C++. Cílem této specifikace je poskytnout model pro paralelní programování, který umožňuje přenos programu napříč architekturami sdílené paměti od různých dodavatelů. Kompilátory od mnoha dodavatelů podporují rozhraní OPENMP C/C++ API. Další informace o OpenMP, včetně rozhraní OpenMP Fortran Application Program, naleznete na následujícím webu:
Direktivy, funkce knihovny a proměnné prostředí definované v tomto dokumentu umožňují vytvářet a spravovat paralelní programy a zároveň umožnit přenositelnost. Direktivy rozšiřují sekvenční programovací model jazyka C a C++ o konstruktory SPMD (Single Program Multiple Data), konstruktory pro sdílení práce a konstrukty synchronizace. Podporují také sdílení a privatizaci dat. Kompilátory, které podporují rozhraní API jazyka C a C++, zahrnují možnost příkazového řádku kompilátoru, který aktivuje a umožňuje interpretaci všech direktiv kompilátoru OpenMP.
1.1 Rozsah
Tato specifikace se týká pouze uživatelem řízené paralelizace, kde explicitně definujete, jaké akce kompilátor a systém za běhu provádějí paralelně program. Implementace OpenMP C a C++ se nevyžadují ke kontrole závislostí, konfliktů, zablokování, podmínek časování nebo jiných problémů, které vedou k nesprávnému spuštění programu. Zodpovídáte za zajištění správného spuštění aplikace pomocí konstruktorů rozhraní API OpenMP c a C++. V tomto dokumentu nejsou popsány direktivy kompilátoru generované automatickým paralelizací a direktivy kompilátoru, které jim pomůžou s takovou paralelizací.
1.2 Definice termínů
V tomto dokumentu se používají následující termíny:
barrier
Synchronizační bod, ke kterému musí mít přístup všechna vlákna v týmu. Každé vlákno čeká, dokud v tomto okamžiku nepřijdou všechna vlákna v týmu. Existují explicitní překážky identifikované direktivami a implicitními bariérami vytvořenými implementací.
konstruovat
Konstruktor je příkaz. Skládá se z direktivy následované strukturovaným blokem. Některé direktivy nejsou součástí konstruktoru. (Viz openmp-direktiva v dodatku C).
směrnice
A C nebo C++
#pragma
následovaný identifikátoremomp
, jiným textem a novým řádkem. Direktiva určuje chování programu.dynamický rozsah
Všechny příkazy v lexikálním rozsahu a všechny příkazy uvnitř funkce, které se provádějí v důsledku provádění příkazů v lexikálním rozsahu. Dynamický rozsah se také označuje jako oblast.
lexikální rozsah
Příkazy lexicky uchovávané v rámci strukturovaného bloku.
hlavní vlákno
Vlákno, které vytvoří tým při zadání paralelní oblasti .
paralelní oblast
Příkazy, které se sváže s paralelním konstruktorem OpenMP a mohou být spouštěny mnoha vlákny.
private
Privátní proměnná pojmenuje blok úložiště, který je jedinečný pro vlákno, které odkazuje. Existuje několik způsobů, jak určit, že proměnná je soukromá: definice v rámci paralelní oblasti, direktivy
threadprivate
private
, ,firstprivate
, ,lastprivate
neboreduction
klauzule, nebo použití proměnné jakofor
řídicí proměnné smyčky vefor
smyčce bezprostředně za direktivou neboparallel for
direktivoufor
.region
Dynamický rozsah.
sériová oblast
Příkazy spouštěné pouze hlavním vláknem mimo dynamický rozsah jakékoli paralelní oblasti.
serializovat
Spuštění paralelního konstruktoru s:
a team of threads skládající se pouze z jednoho vlákna (což je hlavní vlákno pro tento paralelní konstruktor),
serial order of execution for the statements within the structured block (the same order as if the block were not part of a parallel construct) and
žádný vliv na hodnotu vrácenou
omp_in_parallel()
(kromě účinků jakýchkoli vnořených paralelních konstruktorů).
shared
Sdílená proměnná pojmenuje jeden blok úložiště. Všechna vlákna v týmu, které přistupují k této proměnné, přistupují také k tomuto jedinému bloku úložiště.
strukturovaný blok
Strukturovaný blok je příkaz (jeden nebo složený), který má jednu položku a jeden výstup. Pokud se jedná o skok do příkazu nebo z tohoto příkazu, jedná se o strukturovaný blok. (Toto pravidlo zahrnuje volání
longjmp
(3C) nebo použitíthrow
, i když je povoleno voláníexit
.) Pokud jeho provádění vždy začíná na otevření{
a vždy končí na závěr}
, složený příkaz je strukturovaný blok. Příkaz výrazu, příkaz výběru, příkaz iterace nebotry
blok je strukturovaný blok, pokud odpovídající složený příkaz získaný jeho{
uzavřením a}
byl by strukturovaným blokem. Příkaz jump, příkaz s popiskem nebo příkaz deklarace není strukturovaný blok.tým
Jedno nebo více vláken spolupracujících při provádění konstrukce.
vlákno
Entita spuštění má sériový tok řízení, sadu privátních proměnných a přístup ke sdíleným proměnným.
proměnná
Identifikátor, který je volitelně kvalifikovaný názvy oborů názvů, který pojmenuje objekt.
1.3 Model provádění
OpenMP používá model fork-join paralelního spouštění. I když může být tento model fork-join užitečný pro řešení různých problémů, je přizpůsobený pro velké aplikace založené na polích. OpenMP je určen k podpoře programů, které se správně spouští jako paralelní programy (mnoho vláken provádění a úplná knihovna podpory OpenMP). Je to také pro programy, které se správně spouštějí jako sekvenční programy (direktivy ignorovány a jednoduchá knihovna zástupných procedur OpenMP). Je ale možné a povoleno vyvíjet program, který se při postupném spuštění nechová správně. Kromě toho mohou různé stupně paralelismu vést k různým číselným výsledkům kvůli změnám přidružení číselných operací. Například snížení počtu sériových sčítání může mít jiný způsob přidružení sčítání než paralelní redukce. Tato různá přidružení mohou změnit výsledky sčítání s plovoucí desetinou čárkou.
Program napsaný pomocí rozhraní OPENMP C/C++ API začíná spouštění jako jedno vlákno, které se nazývá hlavní vlákno. Hlavní vlákno se spustí v sériové oblasti, dokud nebude zjištěn první paralelní konstruktor. V rozhraní OPENMP C/C++ API představuje parallel
direktiva paralelní konstruktor. Když dojde k paralelnímu konstruktoru, hlavní vlákno vytvoří tým vláken a hlavní vlákno se stane hlavním členem týmu. Každé vlákno v týmu spouští příkazy v dynamickém rozsahu paralelní oblasti s výjimkou konstruktorů pro sdílení práce. Všechna vlákna v týmu musí narazit na konstrukty sdílení práce ve stejném pořadí a jedno nebo více vláken spouští příkazy v přidruženém strukturovaném bloku. Bariéra předpokládaná na konci konstruktoru sdílení práce bez nowait
klauzule se provádí všemi vlákny v týmu.
Pokud vlákno upraví sdílený objekt, ovlivní nejen vlastní spouštěcí prostředí, ale i ostatní vlákna v programu. Změna je zaručena, že bude dokončena, z pohledu jiného vlákna, v dalším bodě sekvence (jak je definováno v základním jazyce) pouze v případě, že je objekt deklarován jako nestálý. V opačném případě je zaručeno, že změny budou dokončeny po prvním úpravě vlákna. Ostatní vlákna pak (nebo souběžně) vidí direktivu flush
, která určuje objekt (implicitně nebo explicitně). flush
Pokud direktivy odvozené jinými direktivy OpenMP nezaručují správné řazení vedlejších účinků, je zodpovědností programátora dodat další explicitní flush
direktivy.
Po dokončení paralelního konstruktoru se vlákna v týmu synchronizují s implicitní bariérou a pouze hlavní vlákno pokračuje ve spouštění. V jednom programu lze zadat libovolný počet paralelních konstruktorů. V důsledku toho může program během provádění forkovat fork a připojit se mnohokrát.
Rozhraní OPENMP C/C++ API umožňuje programátorům používat direktivy ve funkcích volaných z paralelních konstruktorů. Direktivy, které se nezobrazují v lexikálním rozsahu paralelního konstruktoru, ale mohou lhát v dynamickém rozsahu, se nazývají osamocené direktivy. Se osamocenými direktivami můžou programátoři paralelně spouštět velké části svého programu s minimálními změnami v sekvenčním programu. Díky této funkci můžete kódovat paralelní konstrukce na nejvyšších úrovních stromu volání programu a používat direktivy k řízení provádění v některé z volaných funkcí.
Nesynchronizovaná volání výstupních funkcí jazyka C a C++, které zapisují do stejného souboru, mohou vést k tomu, že data zapsaná různými vlákny se zobrazují v nedeterministickém pořadí. Podobně nesynchronizované volání vstupních funkcí, které čtou ze stejného souboru, mohou číst data v nedeterministickém pořadí. Nesynchronizované použití vstupně-výstupních operací, aby každé vlákno přistupuje k jinému souboru, vytvořilo stejné výsledky jako sériové spuštění vstupně-výstupních funkcí.
1.4 Kompatibilita
Implementace rozhraní OPENMP C/C++ API je kompatibilní s OpenMP, pokud rozpozná a zachovává sémantiku všech prvků této specifikace, jak je uvedeno v kapitolách 1, 2, 3, 4 a dodatku C. Dodatky A, B, D, E a F jsou určené pouze pro účely informací a nejsou součástí specifikace. Implementace, které zahrnují pouze podmnožinu rozhraní API, nejsou kompatibilní s OpenMP.
Rozhraní OPENMP C a C++ API je rozšíření základního jazyka podporovaného implementací. Pokud základní jazyk nepodporuje konstruktor jazyka nebo rozšíření, které se zobrazí v tomto dokumentu, implementace OpenMP ji nepodporuje.
Všechny standardní funkce knihovny C a C++ a integrované funkce (to znamená, že funkce, jejichž kompilátor má specifické znalosti), musí být bezpečné pro přístup z více vláken. Nesynchronizované použití funkcí bezpečných pro vlákna různými vlákny uvnitř paralelní oblasti nevyvolá nedefinované chování. Chování ale nemusí být stejné jako v sériové oblasti. (Příkladem je funkce generování náhodných čísel.)
Rozhraní OPENMP C/C++ API určuje, že určité chování je definované implementací. K definování a zdokumentování chování v těchto případech se vyžaduje odpovídající implementace OpenMP. Seznam chování definovaných implementací najdete v dodatku E.
1.5 Normativní odkazy
ISO/IEC 9899:1999, Informační technologie - Programovací jazyky - C. Tato specifikace rozhraní OPENMP API odkazuje na ISO/IEC 9899:1999 jako C99.
ISO/IEC 9899:1990, Informační technologie - Programovací jazyky - C. Tato specifikace rozhraní OPENMP API odkazuje na ISO/IEC 9899:1990 jako C90.
ISO/IEC 14882:1998, Informační technologie - Programovací jazyky - C++. Tato specifikace rozhraní OPENMP API odkazuje na ISO/IEC 14882:1998 jako C++.
Pokud tato specifikace rozhraní OpenMP API odkazuje na jazyk C, odkazuje se na základní jazyk podporovaný implementací.