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


3. Futásidejű kódtárfüggvények

Ez a szakasz az OpenMP C és C++ futásidejű kódtár funkcióit ismerteti. Az omp.h< fejléc> két típust deklarál, több függvényt, amelyek a párhuzamos végrehajtási környezet szabályozására és lekérdezésére használhatók, valamint zárolja az adatokhoz való hozzáférés szinkronizálására használható függvényeket.

A típus omp_lock_t olyan objektumtípus, amely képes jelezni, hogy egy zárolás elérhető, vagy hogy egy szál birtokol egy zárolást. Ezeket a zárakat egyszerű záraknak nevezzük.

A(z) omp_nest_lock_t típus olyan objektumtípus, amely képes jelezni, hogy a zárolás elérhető-e, vagy a zárolást birtokló szál identitását és a beágyazási számot (az alábbiakban ismertetjük). Ezeket a zárakat egymásba ágyazható záraknak nevezzük.

A kódtárfüggvények "C" kapcsolattal rendelkező külső függvények.

Az ebben a fejezetben szereplő leírások a következő témakörökre oszlanak:

3.1 Végrehajtási környezeti függvények

Az ebben a szakaszban ismertetett függvények befolyásolják és figyelik a szálakat, a processzorokat és a párhuzamos környezetet:

3.1.1 omp_set_num_threads függvény

A omp_set_num_threads függvény beállítja az alapértelmezett szálak számát azokhoz a későbbi párhuzamos régiókhoz, amelyek nem határoznak meg num_threads záradékot. A formátum a következő:

#include <omp.h>
void omp_set_num_threads(int num_threads);

A num_threads paraméter értékének pozitív egész számnak kell lennie. Hatása attól függ, hogy engedélyezve van-e a szálak számának dinamikus beállítása. A szálak függvénye és dinamikus beállítása közötti omp_set_num_threads interakcióra vonatkozó átfogó szabálykészletért lásd a 2.3. szakaszt.

Ez a függvény a fent leírt hatásokkal rendelkezik, amikor a program egy olyan részéből hívjuk meg, ahol a omp_in_parallel függvény nullát ad vissza. Ha a program egy olyan részéből hívják, ahol a omp_in_parallel függvény nemero értéket ad vissza, a függvény viselkedése nincs meghatározva.

Ez a hívás elsőbbséget élvez a OMP_NUM_THREADS környezeti változóval szemben. A hívással omp_set_num_threads vagy a OMP_NUM_THREADS környezeti változó beállításával megállapítható szálak számának alapértelmezett értéke explicit módon felülírható egyetlen parallel irányelven a num_threads záradék megadásával.

További információ: omp_set_dynamic.

Kereszthivatkozások

3.1.2 omp_get_num_threads függvény

A omp_get_num_threads függvény azoknak a szálaknak a számát adja vissza, amelyek jelenleg a párhuzamos régiót végrehajtó csapatban futnak. A formátum a következő:

#include <omp.h>
int omp_get_num_threads(void);

A num_threads záradék, a omp_set_num_threads függvény és a OMP_NUM_THREADS környezeti változó szabályozza a csapat szálainak számát.

Ha a felhasználó nem állította be explicit módon a szálak számát, az alapértelmezett érték a implementációban van definiálva. Ez a függvény a legközelebbi körülölelő parallel irányelvhez kötődik. Ha egy program soros részéből vagy egy szerializált beágyazott párhuzamos régióból hívjuk meg, ez a függvény 1-et ad vissza.

További információ: omp_set_dynamic.

Kereszthivatkozások

3.1.3 omp_get_max_threads függvény

A omp_get_max_threads függvény egy olyan egész számot ad vissza, amely garantáltan legalább akkora lesz, mint azoknak a szálaknak a száma, amelyeket egy csapat létrehozásához használna, ha egy záradék nélküli num_threads párhuzamos régiót látna a kód ezen pontján. A formátum a következő:

#include <omp.h>
int omp_get_max_threads(void);

Az alábbiak a következő érték alsó határát omp_get_max_threadsfejezik ki:

szálak-következő-csapatnak-felhasználva< = omp_get_max_threads

Vegye figyelembe, hogy ha egy másik párhuzamos régió a num_threads záradékot használja egy adott számú szál lekérésére, omp_get_max_threads eredményének alsó határára vonatkozó garancia már nem érvényes.

A omp_get_max_threads függvény visszatérési értéke segítségével dinamikusan lefoglalható a megfelelő tárterület a következő párhuzamos régióban létrehozott csapat összes szálához.

Kereszthivatkozások

3.1.4 omp_get_thread_num függvény

A omp_get_thread_num függvény a függvényt végrehajtó szál számát adja vissza a csapatán belül. A szál száma 0 és omp_get_num_threads()-1 között van, a tartomány mindkét szélét beleértve. A csapat főszála a 0. szál.

A formátum a következő:

#include <omp.h>
int omp_get_thread_num(void);

Ha egy soros régióból hívjuk meg, omp_get_thread_num akkor 0 értéket ad vissza. Ha egy szerializált beágyazott párhuzamos régióból hívjuk meg, ez a függvény 0 értéket ad vissza.

Kereszthivatkozások

3.1.5 omp_get_num_procs függvény

A omp_get_num_procs függvény a függvény meghívásakor a program számára elérhető processzorok számát adja vissza. A formátum a következő:

#include <omp.h>
int omp_get_num_procs(void);

3.1.6 omp_in_parallel függvény

A omp_in_parallel függvény nemero értéket ad vissza, ha a függvény a párhuzamosan végrehajtó párhuzamos régió dinamikus kiterjedésén belül van meghívva, ellenkező esetben 0 értéket ad vissza. A formátum a következő:

#include <omp.h>
int omp_in_parallel(void);

Ez a függvény nemero értéket ad vissza, ha egy párhuzamosan végrehajtó régióból hív meg, beleértve a szerializált beágyazott régiókat is.

3.1.7 omp_set_dynamic függvény

A omp_set_dynamic függvény lehetővé teszi vagy letiltja a párhuzamos régiók végrehajtásához rendelkezésre álló szálak számának dinamikus módosítását. A formátum a következő:

#include <omp.h>
void omp_set_dynamic(int dynamic_threads);

Ha dynamic_threads nem nulla értékre értékeli ki, a közelgő párhuzamos régiók végrehajtásához használt szálak számát a futtatókörnyezet automatikusan módosíthatja a rendszererőforrások legjobb kihasználása érdekében. Ennek következtében a felhasználó által megadott szálak száma a maximális szálszám. A párhuzamos szakaszt végrehajtó csapat szálainak száma a szakasz időtartamára fix marad, és a omp_get_num_threads függvény adja vissza.

Ha a dynamic_threads értéke 0, a dinamikus beállítások le vannak tiltva.

Ez a függvény a fent leírt hatásokkal rendelkezik, amikor a program egy olyan részéből hívjuk meg, ahol a omp_in_parallel függvény nullát ad vissza. Ha a program egy olyan részéből hívják, ahol a omp_in_parallel függvény nemero értéket ad vissza, a függvény viselkedése nincs meghatározva.

Egy hívás omp_set_dynamic elsőbbséget élvez a OMP_DYNAMIC környezeti változóval szemben.

A szálak dinamikus beállításának alapértelmezett értéke a implementáció által definiált. Ennek eredményeképpen a megfelelő végrehajtáshoz megadott számú száltól függő felhasználói kódoknak explicit módon le kell tiltania a dinamikus szálakat. Az implementációk nem szükségesek a szálak számának dinamikus módosításához, de az interfésznek minden platformon támogatnia kell a hordozhatóságot.

Microsoft-specifikus

A omp_get_dynamic és omp_set_dynamic jelenlegi támogatása a következő:

A bemeneti paraméter omp_set_dynamic nem befolyásolja a szálkezelési szabályzatot, és nem módosítja a szálak számát. omp_get_num_threads mindig a felhasználó által megadott számot adja vissza, ha ez be van állítva, vagy az alapértelmezett szálszámot. A Microsoft jelenlegi implementációjában kapcsolja ki a dinamikus szálkezelést, omp_set_dynamic(0) hogy a meglévő szálak újra felhasználhatók legyenek a következő párhuzamos régióban. omp_set_dynamic(1) bekapcsolja a dinamikus szálkezelést úgy, hogy elveti a meglévő szálkészletet, és létrehoz egy új készletet a közelgő párhuzamos régióhoz. Az új készlet szálainak száma megegyezik a régi készlettel, és a visszatérési omp_get_num_threadsértéken alapul. Ezért a legjobb teljesítmény érdekében használja omp_set_dynamic(0) a meglévő szálak újrafelhasználására.

Kereszthivatkozások

3.1.8 omp_get_dynamic függvény

A omp_get_dynamic függvény nemero értéket ad vissza, ha a szálak dinamikus beállítása engedélyezve van, és egyébként 0 értéket ad vissza. A formátum a következő:

#include <omp.h>
int omp_get_dynamic(void);

Ha az implementáció nem valósítja meg a szálak számának dinamikus módosítását, ez a függvény mindig 0 értéket ad vissza. További információ: omp_set_dynamic.

Kereszthivatkozások

  • A dinamikus szálbeállítás leírását a omp_set_dynamic című témakörben talál.

3.1.9 omp_set_nested függvény

A omp_set_nested függvény engedélyezi vagy letiltja a beágyazott párhuzamosságot. A formátum a következő:

#include <omp.h>
void omp_set_nested(int nested);

Ha a beágyazott értékelés értéke 0, a beágyazott párhuzamosság le van tiltva, ami az alapértelmezett érték, és a beágyazott párhuzamos régiókat az aktuális szál szerializálja és végrehajtja. Ellenkező esetben a beágyazott párhuzamosság engedélyezve van, és a beágyazott párhuzamos régiók további szálakat helyezhetnek üzembe beágyazott csapatok létrehozásához.

Ez a függvény a fent leírt hatásokkal rendelkezik, amikor a program egy olyan részéből hívjuk meg, ahol a omp_in_parallel függvény nullát ad vissza. Ha a program egy olyan részéből hívják, ahol a omp_in_parallel függvény nemero értéket ad vissza, a függvény viselkedése nincs meghatározva.

Ez a hívás elsőbbséget élvez a OMP_NESTED környezeti változóval szemben.

Ha engedélyezve van a beágyazott párhuzamosság, a beágyazott párhuzamos régiók végrehajtásához használt szálak száma implementálási definícióval van meghatározva. Ennek eredményeképpen az OpenMP-kompatibilis implementációk akkor is szerializálhatják a beágyazott párhuzamos régiókat, ha engedélyezve van a beágyazott párhuzamosság.

Kereszthivatkozások

3.1.10 omp_get_nested függvény

A omp_get_nested függvény nemero értéket ad vissza, ha a beágyazott párhuzamosság engedélyezve van, és 0 értéket, ha le van tiltva. További információ a beágyazott párhuzamosságról: omp_set_nested. A formátum a következő:

#include <omp.h>
int omp_get_nested(void);

Ha egy implementáció nem valósít meg beágyazott párhuzamosságot, ez a függvény mindig 0 értéket ad vissza.

3.2 Zárolási funkciók

Az ebben a szakaszban ismertetett függvények manipulálják a szinkronizáláshoz használt zárolásokat.

A következő függvényekhez a zárolási változónak típussal kell rendelkeznie omp_lock_t. Ezt a változót csak ezeken a függvényeken keresztül lehet elérni. Minden zárolási függvényhez szükség van egy olyan argumentumra, amely egy mutatóval rendelkezik a(z) omp_lock_t típushoz.

A következő függvényekhez a zárolási változónak típussal kell rendelkeznie omp_nest_lock_t. Ezt a változót csak ezeken a függvényeken keresztül lehet elérni. Minden beágyazható zárolási függvényhez szükség van egy argumentumra, amely mutatóval rendelkezik egy omp_nest_lock_t típusú mutatóra.

Az OpenMP zárolási függvények úgy érik el a zárolási változót, hogy mindig olvassák és frissíthessék a zárolási változó legfrissebb értékét. Ezért nem szükséges, hogy egy OpenMP-program explicit flush irányelveket tartalmazzon annak érdekében, hogy a zárolási változó értéke konzisztens legyen a különböző szálak között. (Előfordulhat, hogy további utasításokra van szükség, hogy más változók értékei konzisztenssé váljanak.)

3.2.1 omp_init_lock és omp_init_nest_lock függvények

Ezek a függvények biztosítják a zárolások inicializálásának egyetlen eszközét. Minden függvény inicializálja a paraméterzárhoz társított zárolást a közelgő hívásokban való használathoz. A formátum a következő:

#include <omp.h>
void omp_init_lock(omp_lock_t *lock);
void omp_init_nest_lock(omp_nest_lock_t *lock);

A kezdeti állapot nincs lezárva (azaz egyetlen szál sem birtokolja a zárat). Beágyazott zárolás esetén a kezdeti beágyazási szám nulla. Nem megfelelő bármelyik rutint meghívni egy már inicializált zárolási változóval.

3.2.2 omp_destroy_lock és omp_destroy_nest_lock függvények

Ezek a függvények biztosítják, hogy a mutatott zár változó lock ne legyen inicializálva. A formátum a következő:

#include <omp.h>
void omp_destroy_lock(omp_lock_t *lock);
void omp_destroy_nest_lock(omp_nest_lock_t *lock);

Nem megfelelő a rutinok egyikének meghívása egy nem inicializált vagy feloldott zárolási változóval.

3.2.3 omp_set_lock és omp_set_nest_lock függvények

Mindegyik függvény blokkolja a függvényt végrehajtó szálat, amíg a megadott zárolás el nem érhető, majd beállítja a zárolást. Egy egyszerű zár érhető el, ha fel van oldva. A beágyazható zárolás akkor érhető el, ha nincs zárolva, vagy ha már a függvényt végrehajtó szál tartja. A formátum a következő:

#include <omp.h>
void omp_set_lock(omp_lock_t *lock);
void omp_set_nest_lock(omp_nest_lock_t *lock);

Egyszerű zárolás esetén a függvény argumentumának omp_set_lock inicializált zárolási változóra kell mutatnia. A zárolás tulajdonjogát a függvényt végrehajtó szál kapja meg.

Beágyazott zárolás esetén a függvény argumentumának omp_set_nest_lock inicializált zárolási változóra kell mutatnia. A beágyazási szám növekszik, és a szál vagy megszerzi, vagy megtartja a zár tulajdonjogát.

3.2.4 omp_unset_lock és omp_unset_nest_lock függvények

Ezek a függvények lehetővé teszik a zár tulajdonjogának felszabadítását. A formátum a következő:

#include <omp.h>
void omp_unset_lock(omp_lock_t *lock);
void omp_unset_nest_lock(omp_nest_lock_t *lock);

Az egyes függvények argumentumának egy inicializált zárolási változóra kell mutatnia, amely a függvényt végrehajtó szál tulajdonában van. A viselkedés nincs meghatározva, ha a szál nem rendelkezik ezzel a zárolási funkcióval.

Egyszerű zárolás esetén a omp_unset_lock függvény felszabadítja a függvényt végrehajtó szálat a zárolás tulajdonjogából.

Beágyazott zárolás esetén a omp_unset_nest_lock függvény csökkenti a beágyazási számot, és felszabadítja a függvényt végrehajtó szálat a zárolás tulajdonjogából, ha az eredmény nulla.

3.2.5 omp_test_lock és omp_test_nest_lock függvények

Ezek a függvények megpróbálják beállítani a zárolást, de nem tiltják le a szál végrehajtását. A formátum a következő:

#include <omp.h>
int omp_test_lock(omp_lock_t *lock);
int omp_test_nest_lock(omp_nest_lock_t *lock);

Az argumentumnak inicializált zárolási változóra kell mutatnia. Ezek a függvények ugyanúgy próbálják beállítani a zárolást, mint omp_set_lock és omp_set_nest_lockazzal a kivételrel, hogy nem tiltják le a szál végrehajtását.

Egyszerű zárolás esetén a omp_test_lock függvény nemero értéket ad vissza, ha a zárolás sikeresen be van állítva, ellenkező esetben nulla értéket ad vissza.

Beágyazott zárolás esetén a omp_test_nest_lock függvény az új beágyazási számot adja vissza, ha a zárolás sikeresen be van állítva, ellenkező esetben nulla értéket ad vissza.

3.3 Időzítési rutinok

Az ebben a szakaszban ismertetett függvények támogatják a hordozható falióra időzítőt:

  • A omp_get_wtime függvény a fali óra eltelt idejét adja vissza.
  • A omp_get_wtick függvény másodperceket ad vissza az egymást követő órajelek között.

3.3.1 omp_get_wtime függvény

A omp_get_wtime függvény egy dupla pontosságú lebegőpontos értéket ad vissza, amely megegyezik a fali óra eltelt idejével másodpercek alatt, egy "múltbéli idő" óta. A tényleges "múltbéli idő" tetszőleges, de garantáltan nem változik az alkalmazásprogram végrehajtása során. A formátum a következő:

#include <omp.h>
double omp_get_wtime(void);

A függvény várhatóan a következő példában látható módon méri az eltelt időt:

double start;
double end;
start = omp_get_wtime();
... work to be timed ...
end = omp_get_wtime();
printf_s("Work took %f sec. time.\n", end-start);

A visszaadott idők "szálankénti idők", vagyis nem szükséges, hogy globális szinten következetesek legyenek az alkalmazásban részt vevő összes szál között.

3.3.2 omp_get_wtick függvény

A omp_get_wtick függvény dupla pontosságú lebegőpontos értéket ad vissza, amely megegyezik az egymást követő órajelek közötti másodpercek számával. A formátum a következő:

#include <omp.h>
double omp_get_wtick(void);