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


1. Bevezetés

Ez a dokumentum fordítói irányelvek, kódtárfüggvények és környezeti változók gyűjteményét adja meg, amelyekkel a C és C++ programokban megadhatja a megosztott memória párhuzamosságát. A dokumentumban leírt funkciók együttesen OpenMP C/C++ Alkalmazásprogram-felület (API) néven ismertek. Ennek a specifikációnak az a célja, hogy olyan modellt biztosítson a párhuzamos programozáshoz, amely lehetővé teszi, hogy a program hordozható legyen a különböző gyártók megosztott memória architektúrái között. Számos gyártó fordítói támogatják az OpenMP C/C++ API-t. További információ az OpenMP-ről, beleértve az OpenMP Fortran alkalmazásprogram felületét is, az alábbi webhelyen található:

https://www.openmp.org

A dokumentumban meghatározott irányelvek, kódtárfüggvények és környezeti változók lehetővé teszik párhuzamos programok létrehozását és kezelését, miközben lehetővé teszik a hordozhatóságot. Az irányelvek kiterjesztik a C és C++ szekvenciális programozási modellt egyetlen program több adatból (SPMD) álló szerkezetekkel, munkamegosztási szerkezetekkel és szinkronizálási szerkezetekkel. Emellett az adatok megosztását és privatizációját is támogatják. Az OpenMP C és C++ API-t támogató fordítók parancssori lehetőséget tartalmaznak a fordítóhoz, amely aktiválja és lehetővé teszi az Összes OpenMP-fordítói irányelv értelmezését.

1.1 Hatókör

Ez a specifikáció csak a felhasználó által irányított párhuzamosításra vonatkozik, így explicit módon meghatározhatja, hogy a fordító és a futásidejű rendszer milyen műveleteket végez a program párhuzamos végrehajtásához. Az OpenMP C és C++ implementációk nem szükségesek a függőségek, ütközések, holtpontok, versenyfeltételek vagy egyéb, helytelen programvégrehajtást eredményező problémák kereséséhez. Ön felelős annak biztosításáért, hogy az OpenMP C és C++ API-t használó alkalmazás megfelelően fut. A fordító által létrehozott automatikus párhuzamosítás és a fordítónak az ilyen párhuzamosítást segítő irányelvek nem szerepelnek a dokumentumban.

1.2 A kifejezések meghatározása

A dokumentum a következő kifejezéseket használja:

  • akadály

    Egy olyan szinkronizálási pont, amelyet a csapat összes szálának el kell érnie. Minden szál addig vár, amíg a csapat összes szála meg nem érkezik erre a pontra. Vannak az irányelvek által azonosított explicit korlátok, valamint a végrehajtás során létrehozott implicit korlátok.

  • épít

    A konstrukció egy állítás. Ez egy irányelvből áll, amelyet egy strukturált blokk követ. Egyes irányelvek nem részei a szerkezetnek. (Lásd: openmp-directive a C függelékben).

  • direktíva

    Egy C vagy C++ #pragma érték, amelyet az azonosító, az omp egyéb szöveg és egy új sor követ. Az irányelv meghatározza a program viselkedését.

  • dinamikus kiterjedés

    Minden utasítás a lexikális kiterjedésben, valamint minden olyan utasítás egy függvényen belül, amelyet a lexikális kiterjedésű utasítások végrehajtása eredményeként hajtanak végre. A dinamikus mértéket régiónak is nevezik.

  • lexikális kiterjedés

    A strukturált blokkokban lexikálisan tárolt utasítások.

  • főszál

    Az a szál, amely egy párhuzamos régió beírásakor létrehoz egy csapatot.

  • párhuzamos régió

    Az OpenMP párhuzamos szerkezetéhez kötődő és számos szál által végrehajtható utasítások.

  • privát

    A magánváltozók olyan tárolóblokkot neveznek el, amely egyedi a hivatkozó szálon. Többféleképpen megadhatja, hogy egy változó privát legyen: párhuzamos régióban való definícióval, threadprivate irányelvvel, private, firstprivate, lastprivate vagy reduction záradékkal, illetve a változó for ciklusvezérlő változóként való használatával egy for ciklusban, közvetlenül egy for vagy parallel for irányelv után.

  • régió

    Dinamikus kiterjedés.

  • soros terület

    Csak a főszál által végrehajtott utasítások bármely párhuzamos régió dinamikus kiterjedésén kívül.

  • szerializál

    A párhuzamos szerkezet végrehajtása a következő elemekkel:

    • egy szálból álló csapat, amely csak egyetlen szálból áll (amely a párhuzamos szerkezet főszála),

    • a strukturált blokkon belüli utasítások végrehajtási sorrendje (ugyanaz a sorrend, mintha a blokk nem egy párhuzamos szerkezet része volna), és

    • nincs hatása a visszaadott omp_in_parallel() értékre (a beágyazott párhuzamos szerkezetek hatásán kívül).

  • megosztott

    A megosztott változók egyetlen tárolóblokkot neveznek el. A változót elérő csapat összes szála is hozzáfér ehhez az egyetlen tárterülethez.

  • strukturált blokk

    A strukturált blokk egy olyan utasítás (egy vagy összetett), amely egyetlen belépési és egyetlen kilépéssel rendelkezik. Ha egy utasításba való belépés vagy kilépés történik, akkor az az utasítás egy strukturált blokkot alkot. (Ez a szabály tartalmazza a longjmp(3C) hívását vagy a throw használatát, bár a exit hívása engedélyezett.) Ha a végrehajtás mindig a megnyitáskor { kezdődik, és mindig a zárónál }ér véget, az összetett utasítás strukturált blokk. A kifejezési utasítás, kijelölési utasítás, iterációs utasítás vagy blokk try strukturált blokk, ha a megfelelő összetett utasítás, amit { és } foglal körbe, strukturált blokk lenne. A jump utasítás, a címkézett utasítás vagy a deklarációs utasítás nem strukturált blokk.

  • csapat

    Egy vagy több szál együttműködik egy szerkezet végrehajtásában.

  • beszélgetés

    Egy végrehajtási entitás, amely soros vezérlési folyamatokkal, privát változók készletével és megosztott változókhoz való hozzáféréssel rendelkezik.

  • változó

    Egy azonosító, amely opcionálisan névterek neveivel van megadva, és egy objektumot elnevez.

1.3 Végrehajtási modell

Az OpenMP a párhuzamos végrehajtás elágazásos illesztési modelljét használja. Bár ez az elágazásos modell hasznos lehet a különböző problémák megoldásához, nagy tömbalapú alkalmazásokhoz van testre szabva. Az OpenMP a párhuzamos programokként (számos végrehajtási szál és teljes OpenMP-támogatási kódtár) megfelelően végrehajtó programokat támogatja. Olyan programokhoz is használható, amelyek szekvenciális programokként megfelelően futnak (az utasítások figyelmen kívül hagyásával és egy egyszerűsített OpenMP csonktár használatával). Azonban lehetséges és engedélyezett olyan program fejlesztése, amely nem megfelelően viselkedik a szekvenciális végrehajtáskor. Ezenkívül a különböző párhuzamossági fokok eltérő numerikus eredményeket eredményezhetnek a numerikus műveletek társításának változásai miatt. A soros összeadás csökkentésének például más mintája lehet az összeadási társításoknak, mint a párhuzamos csökkentésnek. Ezek a különböző társítások megváltoztathatják a lebegőpontos hozzáadás eredményeit.

Az OpenMP C/C++ API-val írt programok a végrehajtást egyetlen végrehajtási szálként, úgynevezett főszálként kezdik meg. A főszál egy soros régióban fut, amíg el nem éri az első párhuzamos szerkezetet. Az OpenMP C/C++ API-ban az parallel irányelv párhuzamos szerkezetet alkot. Párhuzamos konstrukció esetén a főszál egy csoportot hoz létre a szálakból, és a főszál lesz a csapat vezetője. A csapat minden szála egy párhuzamos régió dinamikus kiterjedésében hajtja végre az utasításokat, a munkamegosztási szerkezetek kivételével. A csapat összes szálának azonos sorrendben kell munkamegosztási szerkezetekkel találkoznia, és egy vagy több szál végrehajtja a kapcsolódó strukturált blokkon belüli utasításokat. A záradék nélküli nowait munkamegosztási szerkezet végén megjelenő akadályt a csapat összes szála végrehajtja.

Ha egy szál módosít egy megosztott objektumot, az nem csak a saját végrehajtási környezetére, hanem a program többi szálára is hatással van. A módosítás egy másik szál szempontjából garantáltan csak akkor fejeződik be a következő (az alapnyelvben meghatározott) szekvenciaponton, ha az objektumot volatilisnek nyilvánították. Ellenkező esetben a módosítás garantáltan befejeződik a módosító szál első lépése után. A többi szál ekkor (vagy egyidejűleg) egy flush olyan irányelvet lát, amely meghatározza az objektumot (implicit vagy explicit módon). Ha a flush más OpenMP-irányelvek által vélelmezett irányelvek nem garantálják a mellékhatások helyes sorrendjét, a programozó felelőssége, hogy további, explicit flush irányelveket adjon meg.

A párhuzamos szerkezet befejezése után a csapat szálai implicit módon szinkronizálódnak, és csak a főszál folytatja a végrehajtást. Tetszőleges számú párhuzamos szerkezet megadható egyetlen programban. Ennek eredményeképpen egy program sokszor elágaozhat és csatlakozhat a végrehajtás során.

Az OpenMP C/C++ API lehetővé teszi a programozók számára, hogy direktívákat használjanak a párhuzamos szerkezetekből hívott függvényekben. Azokat az irányelveket, amelyek nem jelennek meg a párhuzamos szerkezet lexikális kiterjedésében, de a dinamikus kiterjedésben lehetnek, árva irányelveknek nevezzük. Árva utasítások esetén a programozók a kód jelentős részét párhuzamosan hajthatják végre, a szekvenciális program minimális módosításával. Ezzel a funkcióval a programhívási fa felső szintjein kódokkal kódelheti a párhuzamos szerkezeteket, és irányelvek használatával vezérelheti a végrehajtást az úgynevezett függvények bármelyikében.

Az ugyanahhoz a fájlhoz író C és C++ kimeneti függvények nem aszinkron hívásai olyan kimenetet eredményezhetnek, amelyben a különböző szálak által írt adatok nem meghatározott sorrendben jelennek meg. Hasonlóképpen, az ugyanabból a fájlból beolvasott bemeneti függvények nem aszinkron hívásai nemdeterminista sorrendben is beolvashatják az adatokat. Az I/O nem aszinkron használata, így minden szál egy másik fájlhoz fér hozzá, ugyanazokat az eredményeket eredményezi, mint az I/O-függvények soros végrehajtása.

1.4 Megfelelőség

Az OpenMP C/C++ API implementációja OpenMP-kompatibilis , ha felismeri és megőrzi a specifikáció összes elemének szemantikáját az 1., 2., 3., 4. fejezetben és a C függelékben foglaltak szerint. Az A, B, D, E és F függelékek csak tájékoztatási célokra szolgálnak, és nem részei a specifikációnak. Az API csak egy részhalmazát tartalmazó implementációk nem OpenMP-kompatibilisek.

Az OpenMP C és C++ API az implementáció által támogatott alapnyelv kiterjesztése. Ha az alapnyelv nem támogatja a dokumentumban megjelenő nyelvi szerkezetet vagy bővítményt, az OpenMP-implementáció nem szükséges a támogatásához.

Minden szabványos C és C++ kódtárfüggvénynek és beépített függvénynek (azaz a fordítónak speciális tudással rendelkező függvényeinek) szálbiztosnak kell lennie. A szálbiztos függvények párhuzamos régión belüli különböző szálak általi nem aszinkron használata nem eredményez meghatározatlan viselkedést. Előfordulhat azonban, hogy a viselkedés nem ugyanaz, mint egy soros régióban. (Példa egy véletlenszerű számgenerálási függvény.)

Az OpenMP C/C++ API azt határozza meg, hogy bizonyos viselkedés implementálással van definiálva. Ezekben az esetekben a viselkedés meghatározásához és dokumentálásához megfelelő OpenMP-implementációra van szükség. A implementáció által definiált viselkedések listáját az E függelékben találja.

1.5 Normatív hivatkozások

  • ISO/IEC 9899:1999, Informatika – Programozási nyelvek – C. Ez az OpenMP API-specifikáció az ISO/IEC 9899:1999-et C99-ként jelöli.

  • ISO/IEC 9899:1990, Informatika – Programozási nyelvek – C. Ez az OpenMP API-specifikáció az ISO/IEC 9899:1990-et C90-ként jelöli.

  • ISO/IEC 14882:1998, Informatika - Programozási nyelvek - C++. Ez az OpenMP API-specifikáció az ISO/IEC 14882:1998 szabványra hivatkozik C++ néven.

Ha ez az OpenMP API-specifikáció a C-ra hivatkozik, a rendszer hivatkozik az implementáció által támogatott alapnyelvre.

1.6 Szervezet