Delen via


1. Inleiding

Dit document bevat een verzameling compilerrichtlijnen, bibliotheekfuncties en omgevingsvariabelen die u kunt gebruiken om parallelle uitvoering van gedeeld geheugen in C- en C++-programma's op te geven. De functionaliteit die in dit document wordt beschreven, wordt gezamenlijk de OpenMP C/C++ Application Program Interface (API) genoemd. Het doel van deze specificatie is om een model te bieden voor parallelle programmering waarmee een programma kan worden overdraagbaar in gedeelde geheugenarchitecturen van verschillende leveranciers. Compilers van veel leveranciers ondersteunen de OpenMP C/C++ API. Meer informatie over OpenMP, waaronder de OpenMP Fortran Application Program Interface, vindt u op de volgende website:

https://www.openmp.org

Met de instructies, bibliotheekfuncties en omgevingsvariabelen die in dit document zijn gedefinieerd, kunt u parallelle programma's maken en beheren, terwijl u draagbaarheid toestaat. De instructies breiden het sequentiële programmeermodel C en C++ uit met SPMD-constructies (single program multiple data, work-sharing constructs) en synchronisatieconstructies. Ze ondersteunen ook het delen en privatiseringen van gegevens. Compilers die ondersteuning bieden voor de OpenMP C- en C++-API, bevatten een opdrachtregeloptie voor de compiler die wordt geactiveerd en waarmee alle OpenMP-compilerrichtlijnen kunnen worden geïnterpreteerd.

1.1 Bereik

Deze specificatie omvat alleen door de gebruiker gerichte parallelle uitvoering, waarbij u expliciet definieert welke acties de compiler en het runtimesysteem ondernemen om het programma parallel uit te voeren. OpenMP C- en C++-implementaties zijn niet vereist om te controleren op afhankelijkheden, conflicten, impasses, racevoorwaarden of andere problemen die leiden tot onjuiste uitvoering van het programma. U bent verantwoordelijk voor het correct uitvoeren van de toepassing met behulp van de OpenMP C- en C++ API-constructies. Door compiler gegenereerde automatische parallelle uitvoering en instructies aan de compiler om dergelijke parallelle uitvoering te ondersteunen, worden niet behandeld in dit document.

1.2 Definitie van termen

De volgende termen worden in dit document gebruikt:

  • barrière

    Een synchronisatiepunt dat alle threads in een team moeten bereiken. Elke thread wacht totdat alle threads in het team op dit punt aankomen. Er zijn expliciete belemmeringen geïdentificeerd door richtlijnen en impliciete barrières die door de tenuitvoerlegging zijn gecreëerd.

  • bouwen

    Een construct is een uitspraak. Het bestaat uit een richtlijn, gevolgd door een gestructureerd blok. Sommige instructies maken geen deel uit van een constructie. (Zie openmp-directive in bijlage C).

  • richtlijn

    Een C of C++ #pragma gevolgd door de omp id, andere tekst en een nieuwe regel. De richtlijn geeft programmagedrag aan.

  • dynamische omvang

    Alle instructies in de lexicale mate, plus een instructie in een functie die wordt uitgevoerd als gevolg van de uitvoering van instructies binnen de lexicale omvang. Een dynamische omvang wordt ook wel een regio genoemd.

  • lexicale omvang

    Verklaringen die lexisch in een gestructureerd blok worden bewaard.

  • hoofdthread

    De thread waarmee een team wordt gemaakt wanneer een parallelle regio wordt ingevoerd.

  • parallelle regio

    Instructies die verbinding maken met een openMP-parallelle constructie en die door veel threads kunnen worden uitgevoerd.

  • privé

    Een privévariabele noemt een blok opslag dat uniek is voor de thread die de verwijzing maakt. Er zijn verschillende manieren om op te geven dat een variabele privé is: een definitie binnen een parallelle regio, een threadprivate richtlijn, een privatefirstprivate, of lastprivatereductioncomponent, of het gebruik van de variabele als lusbesturingsvariabele for in een for lus direct na een for of parallel for instructie.

  • regio

    Een dynamische omvang.

  • seriële regio

    Instructies die alleen worden uitgevoerd door de hoofdthread buiten de dynamische omvang van een parallelle regio.

  • serialiseren

    Een parallelle constructie uitvoeren met:

    • een team van threads bestaande uit slechts één thread (de masterthread voor die parallelle constructie)

    • seriële volgorde van uitvoering voor de instructies binnen het gestructureerde blok (dezelfde volgorde als als het blok geen deel uitmaakt van een parallelle constructie) en

    • geen effect op de waarde die wordt geretourneerd door omp_in_parallel() (afgezien van de effecten van geneste parallelle constructies).

  • gedeeld

    Een gedeelde variabele benoemt een enkel blok opslagruimte. Alle threads in een team die toegang hebben tot deze variabele, hebben ook toegang tot dit enkele opslagblok.

  • gestructureerd blok

    Een gestructureerd blok is een instructie (enkel of samengesteld) met één ingang en één uitgang. Als er een sprong naar of uit een verklaring bestaat, dan is die verklaring een gestructureerd blok. (Deze regel bevat een aanroep naar longjmp(3C) of het gebruik van throw, hoewel een aanroep naar exit is toegestaan.) Als de uitvoering altijd begint bij de opening { en altijd eindigt bij het sluiten }, is een samengestelde instructie een gestructureerd blok. Een expressie-instructie, selectie-instructie, iteratie-instructie of try blok is een gestructureerd blok als de bijbehorende samengestelde instructie die is verkregen door deze in { te sluiten en } een gestructureerd blok zou zijn. Een jump-instructie, gelabelde instructie of declaratie-instructie is geen gestructureerd blok.

  • ploeg

    Een of meer threads die samenwerken bij de uitvoering van een construct.

  • draad

    Een uitvoeringsentiteit met een seriële controlestroom, een set privévariabelen en toegang tot gedeelde variabelen.

  • veranderlijk

    Een id, optioneel gekwalificeerd door naamruimtenamen, die een object een naam geven.

1.3 Uitvoeringsmodel

OpenMP maakt gebruik van het fork-joinmodel van parallelle uitvoering. Hoewel het fork-joinmodel handig kan zijn voor het oplossen van verschillende problemen, is het aangepast voor grote op arrays gebaseerde toepassingen. OpenMP is bedoeld ter ondersteuning van programma's die zowel als parallelle programma's (veel threads van uitvoering en een volledige OpenMP-ondersteuningsbibliotheek) correct worden uitgevoerd. Het is ook voor programma's die correct worden uitgevoerd als sequentiële programma's (instructies genegeerd en een eenvoudige OpenMP stubs-bibliotheek). Het is echter mogelijk en toegestaan om een programma te ontwikkelen dat zich niet correct gedraagt wanneer het sequentieel wordt uitgevoerd. Bovendien kunnen verschillende mate van parallelle uitvoering leiden tot verschillende numerieke resultaten vanwege wijzigingen in de koppeling van numerieke bewerkingen. Een seriële toevoegingsreductie kan bijvoorbeeld een ander patroon hebben van toevoegingskoppelingen dan een parallelle reductie. Deze verschillende associaties kunnen de resultaten van drijvende-komma-optelling wijzigen.

Een programma dat is geschreven met de OpenMP C/C++ API begint met de uitvoering als één thread van uitvoering, de hoofdthread genoemd. De hoofdthread wordt uitgevoerd in een seriële regio totdat de eerste parallelle constructie is aangetroffen. In de OpenMP C/C++ API vormt de parallel instructie een parallelle constructie. Wanneer er een parallelle constructie wordt aangetroffen, maakt de hoofdthread een team van threads en wordt de master master van het team. Elke thread in het team voert de instructies uit in de dynamische omvang van een parallelle regio, met uitzondering van de constructies voor het delen van werk. Alle threads in het team moeten werkdelingsconstructies in dezelfde volgorde tegenkomen en een of meer threads voeren de instructies uit binnen het bijbehorende gestructureerde blok. De barrière die aan het einde van een werkdelingsconstructie zonder een nowait component wordt geïmpliceerd, wordt uitgevoerd door alle threads in het team.

Als een thread een gedeeld object wijzigt, heeft dit niet alleen invloed op de eigen uitvoeringsomgeving, maar ook op die van de andere threads in het programma. De wijziging is gegarandeerd voltooid, vanuit het oogpunt van een andere thread, op het volgende reekspunt (zoals gedefinieerd in de basistaal) alleen als het object wordt gedeclareerd om vluchtig te zijn. Anders is de wijziging gegarandeerd voltooid na de eerste modificerende thread. De andere threads (of gelijktijdig) zien vervolgens een flush richtlijn waarmee het object (impliciet of expliciet) wordt opgegeven. Wanneer de flush richtlijnen die worden geïmpliceerd door andere OpenMP-richtlijnen niet de juiste volgorde van bijwerkingen garanderen, is het de verantwoordelijkheid van de programmeur om aanvullende, expliciete flush instructies te leveren.

Na voltooiing van de parallelle constructie synchroniseren de threads in het team bij een impliciete barrière, en alleen de hoofdthread zet de uitvoering voort. Een willekeurig aantal parallelle constructies kan worden opgegeven in één programma. Als gevolg hiervan kan een programma tijdens de uitvoering vaak 'fork' en 'join' operaties uitvoeren.

Met de OpenMP C/C++ API kunnen programmeurs instructies gebruiken in functies die vanuit parallelle constructies worden aangeroepen. Richtlijnen die niet worden weergegeven in de lexicale omvang van een parallelle constructie, maar die in de dynamische mate kunnen liggen, worden verweesde instructies genoemd. Met zwevende instructies kunnen programmeurs grote delen van hun programma parallel uitvoeren, met slechts minimale wijzigingen in het sequentiële programma. Met deze functionaliteit kunt u parallelle constructies codeeren op de hoogste niveaus van de aanroepstructuur van het programma en instructies gebruiken om de uitvoering in een van de aangeroepen functies te beheren.

Niet-gesynchroniseerde aanroepen naar C- en C++-uitvoerfuncties die naar hetzelfde bestand schrijven, kunnen leiden tot uitvoer waarin gegevens die door verschillende threads zijn geschreven, in niet-deterministische volgorde worden weergegeven. Op dezelfde manier kunnen niet-gesynchroniseerde aanroepen naar invoerfuncties die uit hetzelfde bestand worden gelezen, gegevens in niet-deterministische volgorde lezen. Niet-gesynchroniseerd gebruik van I/O, zodat elke thread toegang heeft tot een ander bestand, levert dezelfde resultaten op als de seriële uitvoering van de I/O-functies.

1.4 Naleving

Een implementatie van de OpenMP C/C++ API is OpenMP-compatibel als deze de semantiek van alle elementen van deze specificatie herkent en behoudt, zoals is uiteengezet in hoofdstukken 1, 2, 3, 4 en bijlage C. Appendices A, B, D, E en F zijn alleen bedoeld voor informatiedoeleinden en maken geen deel uit van de specificatie. Implementaties die alleen een subset van de API bevatten, zijn niet openMP-compatibel.

De OpenMP C- en C++ API is een extensie voor de basistaal die wordt ondersteund door een implementatie. Als de basistaal geen ondersteuning biedt voor een taalconstructie of -extensie die in dit document wordt weergegeven, is de OpenMP-implementatie niet vereist om deze te ondersteunen.

Alle standaardbibliotheekfuncties voor C en C++ en ingebouwde functies (dat wil gezegd, functies waarvan de compiler specifieke kennis heeft) moeten thread-safe zijn. Niet-gesynchroniseerd gebruik van threadveilige functies door verschillende threads in een parallelle regio produceert geen niet-gedefinieerd gedrag. Het gedrag is echter mogelijk niet hetzelfde als in een seriële regio. (Een functie voor het genereren van willekeurige getallen is een voorbeeld.)

De OpenMP C/C++ API geeft aan dat bepaald gedrag is gedefinieerd door de implementatie. In deze gevallen is een conforme OpenMP-implementatie vereist om het gedrag ervan te definiëren en te documenteren. Zie bijlage E voor een lijst met door de implementatie gedefinieerde gedragingen.

1.5 Normatieve verwijzingen

  • ISO/IEC 9899:1999, Informatietechnologie - Programmeertalen - C. Deze OpenMP API-specificatie verwijst naar ISO/IEC 9899:1999 als C99.

  • ISO/IEC 9899:1990, Informatietechnologie - Programmeertalen - C. Deze OpenMP API-specificatie verwijst naar ISO/IEC 9899:1990 als C90.

  • ISO/IEC 14882:1998, Informatietechnologie - Programmeertalen - C++. Deze OpenMP API-specificatie verwijst naar ISO/IEC 14882:1998 als C++.

Wanneer deze OpenMP API-specificatie verwijst naar C, wordt verwezen naar de basistaal die wordt ondersteund door de implementatie.

1.6 Organisatie