OpenMP

OpenMP

embléma
Alapadatok

fejlesztő Kompatibilis fordítók listája
Jelenlegi  verzió 5.1
(2020. november)
A jelenlegi előzetes verzió -
operációs rendszer Linux , Unix , Microsoft Windows NT
programozási nyelv C , C ++
kategória API
Engedély ismeretlen (nyitott)
Németül beszélő nem
openmp.org/

OpenMP (Open Multi-Processing) egy közösen, 1997 óta számos hardver - és fordító gyártó kifejlesztett programozási interfész (API) osztott memória programozás C ++ , C és Fortran a többprocesszoros - számítógépek .

Az OpenMP a szálakban végrehajtott ciklusok szintjén párhuzamba állítja a programokat , és ez különbözik a többi megközelítéstől (pl. MPI ), amelyben az egész folyamat párhuzamosan fut, és üzenetváltással hat egymásra.

Az OpenMP szabvány erre a célra speciális fordítói irányelveket határoz meg, amelyek aztán utasítják őket, pl. B. hogy a for ciklus feldolgozását több szálon vagy processzoron elosztja . Alternatívaként léteznek könyvtári funkciók és környezeti változók az OpenMP programozáshoz.

Az OpenMP megosztott fő memóriájú rendszereken ("megosztott memória" gépeken) (úgynevezett UMA és NUMA rendszerek) használható, míg más megközelítések, például az üzenetátadó interfész , a PVM nagyobb valószínűséggel használhatók többszámítógépeken ("osztott memória") "gépek". A modern szuperszámítógépekben gyakran használják az OpenMP -t és az MPI -t (Message Passing Interface). Az MPI -n keresztül kicserélt OpenMP folyamatok egyéni megosztott memória klienseken futnak.

Az OpenMP egyik tulajdonsága, hogy (néhány kivételtől eltekintve) a programok is megfelelően futnak, ha a fordító nem ismeri az OpenMP utasításokat (lásd az alábbi példát), és megjegyzésként értékeli azokat (azaz figyelmen kívül hagyja őket). Ennek az az oka, hogy az OpenMP -vel több szálra osztott forhurok is szekvenciálisan feldolgozható egyetlen szállal.

Főbb összetevők

Az OpenMP fő alkotóelemei a szálak generálására szolgáló konstrukciók, a terhelések több szálon történő elosztása , az adatok körének kezelése, a szinkronizálás, a futásidejű rutinok és a környezeti változók. A szálgenerálás : omp párhuzamos a programot (az eredeti szálat) több szálra osztja fel, így a konstrukció által bezárt programrész párhuzamosan kerül feldolgozásra. Az eredeti szálat „master thread” -nek hívják, és „0” azonosítóval rendelkezik.

Példa: „Hello, World!” Kimenet többször, több szál használatával (minden szál kimenetet generál).

#include <stdio.h>

int main() {
#pragma omp parallel
    puts("Hallo, Welt!\n");

    return 0;
}

A terheléselosztó konstrukciók határozzák meg, hogy az egyidejű, független munkaterhelés hogyan oszlik meg a párhuzamos szálakon. Az Omp for és az omp osztja a ciklusfuttatásokat (ha lehetséges) egyenletesen az összes szálon ( területosztás , "adatpartíció"). A szakaszok egymást követő, de független programrészeket több szálon osztják szét (függvényosztás, "függvénypartíció").

Példa: Egy nagy táblát ("tömb") inicializál párhuzamosan, minden szál inicializálva egy részt (területosztás).

#define N 100000

int main() {
    int a[N];

#pragma omp parallel for
    for (int i = 0; i < N; ++i)
        a[i] = 2 * i;

    return 0;
}

Az adatok érvényességi területének adminisztrációja különböző programozással befolyásolható. A megosztott memória programozásával az adatok nagy része kezdetben minden szálban látható. Egyes programok privát adatokat igényelnek, azaz csak egy szál számára láthatók, és kifejezett értékcserét igényelnek a szekvenciális és a párhuzamos szakaszok között. Az úgynevezett adatokat záradékokat használnak erre a OpenMP . A megosztott típus leírja, hogy az adatok láthatóak és minden szál megváltoztatható. Ugyanazon a memóriahelyen vannak minden szálnál. További információk nélkül az adatok gyakori adatok. Ez alól egyetlen kivétel a ciklusváltozók . A saját , minden szál saját példányát az adatok, amelyek nem törlődnek. Az értékek nem maradnak meg a párhuzamos szakaszon kívül. A privát típus felosztható első privát és utolsó privátra , amelyek kombinálhatók is. Az előbbiben az adatok privátak, azzal a különbséggel, hogy a párhuzamos szakasz előtti utolsó értékkel inicializálják. A Lastprivate abban különbözik, hogy az utolsó iterációt végrehajtó szál másolja az értéket a párhuzamos szakaszból.

Létezik a globális adatok szál-privát típusa is, amelyet azonban a párhuzamos program részben privátként kezelnek. A globális érték megmarad a párhuzamos szakaszon. Copyin analóg firstprivate a privát adatokat, de az tépőszálas privát adatok , amelyek nem törlődnek. A Copyin segítségével a globális érték kifejezetten átkerül a privát adatokhoz. A másolás nem szükséges, mivel a globális érték megmarad. A típuscsökkentéssel az adatok privátak, de a végén globális értékre összesítik (redukálják). Például egy tömb összes elemének összege párhuzamosan határozható meg.

A szálak szinkronizálásához különféle konstrukciókat használnak, például: B. Kritikus szakasz , ahol a mellékelt program részt minden szál végrehajtja, de soha nem egyszerre, vagy akadályt jelölő akadályt, ahol minden szál megvárja, amíg a csoport többi szála is eléri a korlátot. Az atomi parancs analóg a kritikus szakaszhoz , de megjegyzést fűz a fordítóhoz a speciális hardverfunkciók használatához. A fordítót nem köti ez a megjegyzés; figyelmen kívül hagyhatja. Ésszerű az atomic használatát az adatok kizárólagos frissítésére. Az öblítés egy szinkronizálási pontot jelöl, ahol egységes memóriaképet kell létrehozni. A privát adatok visszaíródnak a fő memóriába. Az egyszeres azt jelenti, hogy a mellékelt programrészt csak az a szál hajtja végre, amelyik először eléri azt; ez korlátot jelent a mondat végén, és ezért egyenértékű egy adott pont gátjával . A Master analóg a single -vel, azzal a különbséggel, hogy a mellékelt programrészt a master szál hajtja végre, és a mondat végén nincs akadály.

Ezekben a folyamatokban a futásidejű rutinokat használják például a szálak számának meghatározására a futás közben, és annak meghatározására, hogy a program jelenleg párhuzamos vagy szekvenciális állapotban van -e .

Ebben az összefüggésben a környezeti változók olyan információkat szolgáltatnak, mint a szál -azonosító. Az OpenMP programok végrehajtása bizonyos környezeti változók specifikus megváltoztatásával megváltoztatható. Például a szálak száma és a hurok párhuzamossága befolyásolható futásidőben.

Mintakód

A következő kód szemlélteti a for loop párhuzamos végrehajtását OpenMP használatával. Az érintett szálak számától függően a hurok kis szakaszokra oszlik, amelyek mindegyike egy szálhoz van rendelve. Ez biztosítja, hogy minden szál egyszerre számoljon.

#include <omp.h>
#include <stdio.h>

int main() {
    omp_set_num_threads(4);

#pragma omp parallel for
    for (int i = 0; i < 4; ++i) {
        const int id = omp_get_thread_num();

        printf("Hello World from thread %d\n", id);

        // Nur im Master-Thread ausführen
        if (id == 0)
            printf("There are %d threads\n", omp_get_num_threads());
    }

    return 0;
}

Fordításkor meg kell mondania a fordítónak, hogy kövesse a pragma utasításokat, és tartalmazza az omp függvényekhez szükséges könyvtárakat. Ez az opcióval gccvagy annak clangsegítségével működik -fopenmp.

% gcc -fopenmp example.c -o example
% ./example
Hello World from thread 3
Hello World from thread 0
Hello World from thread 1
Hello World from thread 2
There are 4 threads

A programban lévő szálak számának megadása helyett ez futási időben is megadható. Ehhez állítsa a környezeti változót OMP_NUM_THREADSa kívánt értékre.

% OMP_NUM_THREADS=4 ./example
Hello World from thread 3
Hello World from thread 0
Hello World from thread 1
Hello World from thread 2
There are 4 threads

Végrehajtás

Az OpenMP a legtöbb fordítóba beépített.

  • Microsoft Visual C ++ 2005, 2008 és 2010 (Professional, Team System, Premium és Ultimate Edition),
  • Intel Parallel Studio különböző processzorokhoz (OpenMP 3.1 a 13. verzióból),
  • GCC a 4.2 -es verzióból (OpenMP 4.0 az 5.0 -ás verzióból),
  • Clang / LLVM (OpenMP 3.1 a 3.6.1 verzióból),
  • Oracle Solaris Studio fordító és eszközök Solaris OS (UltraSPARC és x86 / x64) és Linux rendszerekhez,
  • Fortran, C és C ++ fordítók a Portland Csoportból (OpenMP 2.5),
  • Gfortran ,
  • IBM XL C / C ++ fordító,
  • Nanos fordító
  • Pelles C (OpenMP 3.1 a 8. verzióból)

web Linkek

Egyéni bizonyíték

  1. https://gcc.gnu.org/gcc-5/changes.html