Delen via


3. Runtime-bibliotheekfuncties

In deze sectie worden de OpenMP C- en C++-runtimefuncties beschreven. De header <omp.h> declareert twee typen, verschillende functies die kunnen worden gebruikt om de parallelle uitvoeringsomgeving te beheren en er query's op uit te voeren en functies te vergrendelen die kunnen worden gebruikt om de toegang tot gegevens te synchroniseren.

Het type omp_lock_t is een objecttype dat kan voorstellen dat een vergrendeling beschikbaar is of dat een thread eigenaar is van een vergrendeling. Deze vergrendelingen worden eenvoudige vergrendelingen genoemd.

Het type omp_nest_lock_t is een objecttype dat kan voorstellen dat een vergrendeling beschikbaar is, of zowel de identiteit van de thread die eigenaar is van de vergrendeling en een nestingsaantal (zoals hieronder wordt beschreven). Deze vergrendelingen worden geneste vergrendelingen genoemd.

De bibliotheekfuncties zijn externe functies met 'C'-koppeling.

De beschrijvingen in dit hoofdstuk zijn onderverdeeld in de volgende onderwerpen:

3.1 Uitvoeringsomgevingsfuncties

De functies die in deze sectie worden beschreven, hebben invloed op threads, processors en de parallelle omgeving.

3.1.1 functie omp_set_num_threads

Met de omp_set_num_threads functie stel je het standaardaantal threads in voor latere parallelle regio's die geen num_threads clausule specificeren. De indeling is als volgt:

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

De waarde van de parameter num_threads moet een positief geheel getal zijn. Het effect is afhankelijk van of dynamische aanpassing van het aantal threads is ingeschakeld. Zie omp_set_num_threads voor een uitgebreide set regels over de interactie tussen de functie en dynamische aanpassing van threads.

Deze functie heeft de hierboven beschreven effecten wanneer deze worden aangeroepen vanuit een deel van het programma waarin de omp_in_parallel functie nul retourneert. Als deze wordt aangeroepen vanuit een deel van het programma waarin de omp_in_parallel functie een niet-nulwaarde retourneert, is het gedrag van deze functie niet gedefinieerd.

Deze aanroep heeft voorrang op de OMP_NUM_THREADS omgevingsvariabele. De standaardwaarde voor het aantal threads, dat kan worden ingesteld door omp_set_num_threads aan te roepen of door de OMP_NUM_THREADS omgevingsvariabele in te stellen, kan expliciet worden overschreven voor één parallel richtlijn door de num_threads clausule op te geven.

Zie omp_set_dynamic voor meer informatie.

Kruisverwijzingen

3.1.2 functie omp_get_num_threads

De omp_get_num_threads functie retourneert het aantal threads dat zich momenteel in het team bevindt dat de parallelle regio uitvoert waaruit deze wordt aangeroepen. De indeling is als volgt:

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

De num_threads component, de omp_set_num_threads functie en de OMP_NUM_THREADS omgevingsvariabele bepalen het aantal threads in een team.

Als het aantal threads niet expliciet is ingesteld door de gebruiker, wordt de standaardinstelling gedefinieerd door de implementatie. Deze functie bindt aan de dichtstbijzijnde insluitrichtlijn parallel . Als deze functie wordt aangeroepen vanuit een serieel gedeelte van een programma of vanuit een geneste parallelle regio die is geserialiseerd, retourneert deze functie 1.

Zie omp_set_dynamic voor meer informatie.

Kruisverwijzingen

3.1.3 functie omp_get_max_threads

De omp_get_max_threads functie retourneert een geheel getal dat gegarandeerd zo groot is als het aantal threads dat zou worden gebruikt om een team te vormen als een parallelle regio zonder component num_threads op dat moment in de code zou worden gezien. De indeling is als volgt:

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

Hieronder wordt een ondergrens weergegeven voor de waarde van omp_get_max_threads:

threads-used-for-next-team<= omp_get_max_threads

Houd er rekening mee dat als een andere parallelle regio de num_threads clausule gebruikt om een specifiek aantal threads aan te vragen, de garantie op de ondergrens van het resultaat van omp_get_max_threads niet langer geldt.

De retourwaarde van de omp_get_max_threads functie kan worden gebruikt om dynamisch voldoende opslag toe te wijzen voor alle threads in het team dat is gevormd in de volgende parallelle regio.

Kruisverwijzingen

3.1.4 functie omp_get_thread_num

De omp_get_thread_num-functie retourneert het threadnummer van de thread die de functie uitvoert binnen zijn team. Het threadnummer ligt tussen 0 en omp_get_num_threads()-1, inclusief. De hoofdthread van het team is thread 0.

De indeling is als volgt:

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

Als het wordt aangeroepen vanuit een seriële regio, retourneert omp_get_thread_num 0. Als deze functie wordt aangeroepen vanuit een geneste parallelle regio die wordt geserialiseerd, retourneert deze functie 0.

Kruisverwijzingen

3.1.5 omp_get_num_procs functie

De omp_get_num_procs functie retourneert het aantal processors dat beschikbaar is voor het programma op het moment dat de functie wordt aangeroepen. De indeling is als volgt:

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

3.1.6 omp_in_parallel, functie

De omp_in_parallel functie retourneert een niet-nulwaarde als deze wordt aangeroepen binnen de dynamische omvang van een parallelle regio die parallel wordt uitgevoerd. Anders retourneert deze 0. De indeling is als volgt:

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

Deze functie retourneert een niet-nulwaarde wanneer deze wordt aangeroepen vanuit een regio die parallel wordt uitgevoerd, inclusief geneste regio's die worden geserialiseerd.

3.1.7 omp_set_dynamic functie

Met de omp_set_dynamic functie kunt u dynamisch aanpassen van het aantal threads dat beschikbaar is voor het uitvoeren van parallelle regio's. De indeling is als volgt:

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

Als dynamic_threads resulteert in een niet-nulwaarde, kan het aantal threads dat wordt gebruikt voor het uitvoeren van toekomstige parallelle regio's, automatisch worden aangepast door de runtime-omgeving om systeembronnen het beste te gebruiken. Als gevolg hiervan is het aantal threads dat door de gebruiker is opgegeven, het maximumaantal threads. Het aantal threads in het team dat een parallelle regio uitvoert, blijft vast voor de duur van die parallelle regio en wordt gerapporteerd door de omp_get_num_threads functie.

Als dynamic_threads resulteert in 0, wordt dynamische aanpassing uitgeschakeld.

Deze functie heeft de hierboven beschreven effecten wanneer deze worden aangeroepen vanuit een deel van het programma waarin de omp_in_parallel functie nul retourneert. Als deze wordt aangeroepen vanuit een deel van het programma waarin de omp_in_parallel functie een niet-nulwaarde retourneert, is het gedrag van deze functie niet gedefinieerd.

Een aanroep die omp_set_dynamic voorrang heeft op de OMP_DYNAMIC omgevingsvariabele.

De standaardinstelling voor de dynamische aanpassing van threads is door de implementatie gedefinieerd. Als gevolg hiervan moeten gebruikerscodes die afhankelijk zijn van een specifiek aantal threads voor de juiste uitvoering, dynamische threads expliciet uitschakelen. Implementaties zijn niet vereist om het aantal threads dynamisch aan te passen, maar ze zijn vereist om de interface te bieden ter ondersteuning van draagbaarheid op alle platforms.

Microsoft-specifiek

De huidige ondersteuning van omp_get_dynamic en omp_set_dynamic is als volgt:

De invoerparameter naar omp_set_dynamic heeft geen invloed op het threadingbeleid en wijzigt het aantal threads niet. omp_get_num_threads retourneert altijd het door de gebruiker gedefinieerde nummer, als dat is ingesteld of het standaardthreadnummer. In de huidige Microsoft-implementatie omp_set_dynamic(0) schakelt u dynamische threading uit, zodat de bestaande set threads opnieuw kan worden gebruikt voor de volgende parallelle regio. omp_set_dynamic(1) schakelt dynamische threading in door de bestaande set threads te verwijderen en een nieuwe set te maken voor de komende parallelle regio. Het aantal threads in de nieuwe set is hetzelfde als de oude set en is gebaseerd op de retourwaarde van omp_get_num_threads. Gebruik daarom voor de beste prestaties omp_set_dynamic(0) om de bestaande threads opnieuw te gebruiken.

Kruisverwijzingen

3.1.8 functie omp_get_dynamic

De omp_get_dynamic functie retourneert een niet-nulwaarde als dynamische aanpassing van threads is ingeschakeld en retourneert anders 0. De indeling is als volgt:

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

Als de implementatie geen dynamische aanpassing van het aantal threads implementeert, retourneert deze functie altijd 0. Zie omp_set_dynamic voor meer informatie.

Kruisverwijzingen

3.1.9 functie omp_set_nested

De omp_set_nested functie schakelt geneste parallelle uitvoering in of uit. De indeling is als volgt:

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

Als geneste parallelle uitvoering naar 0 evalueert, is geneste parallelle uitvoering uitgeschakeld. Dit is de standaardinstelling, en geneste parallelle gebieden worden geserialiseerd en door de huidige thread uitgevoerd. Anders is geneste parallelle uitvoering ingeschakeld en kunnen parallelle regio's die zijn genest extra threads implementeren om geneste teams te vormen.

Deze functie heeft de hierboven beschreven effecten wanneer deze worden aangeroepen vanuit een deel van het programma waarin de omp_in_parallel functie nul retourneert. Als deze wordt aangeroepen vanuit een deel van het programma waarin de omp_in_parallel functie een niet-nulwaarde retourneert, is het gedrag van deze functie niet gedefinieerd.

Deze aanroep heeft voorrang op de OMP_NESTED omgevingsvariabele.

Wanneer geneste parallelle uitvoering is ingeschakeld, wordt het aantal threads dat wordt gebruikt voor het uitvoeren van geneste parallelle regio's gedefinieerd door de implementatie. Als gevolg hiervan mogen OpenMP-compatibele implementaties een geneste parallelle regio serialiseren, zelfs wanneer geneste parallelle verwerking is ingeschakeld.

Kruisverwijzingen

3.1.10 functie omp_get_nested

De omp_get_nested functie retourneert een niet-nulwaarde als geneste parallelle uitvoering is ingeschakeld en 0 als deze is uitgeschakeld. Zie omp_set_nested voor meer informatie over geneste parallelisme. De indeling is als volgt:

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

Als een implementatie geen geneste parallelle uitvoering implementeert, retourneert deze functie altijd 0.

3.2 Vergrendelingsfuncties

De functies die in deze sectie worden beschreven, manipuleren vergrendelingen die worden gebruikt voor synchronisatie.

Voor de volgende functies moet de vergrendelingsvariabele type omp_lock_thebben. Deze variabele mag alleen worden geopend via deze functies. Alle vergrendelingsfuncties vereisen een argument met een aanwijzer naar het type omp_lock_t.

Voor de volgende functies moet de vergrendelingsvariabele type omp_nest_lock_thebben. Deze variabele mag alleen worden geopend via deze functies. Alle neste vergrendelingsfuncties vereisen een argument dat een aanwijzer naar type omp_nest_lock_t heeft.

De OpenMP-vergrendelingsfuncties hebben toegang tot de vergrendelingsvariabele op een zodanige manier dat ze altijd de meest recente waarde van de vergrendelingsvariabele lezen en bijwerken. Daarom is het niet nodig dat een OpenMP-programma expliciete flush instructies bevat om ervoor te zorgen dat de waarde van de vergrendelingsvariabele consistent is tussen verschillende threads. (Er zijn mogelijk richtlijnen nodig flush om de waarden van andere variabelen consistent te maken.)

3.2.1 omp_init_lock en omp_init_nest_lock functies

Deze functies bieden de enige middelen om een vergrendeling te initialiseren. Elke functie initialiseert de vergrendeling die is gekoppeld aan de parametervergrendeling voor gebruik in toekomstige aanroepen. De indeling is als volgt:

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

De initiële status is ontgrendeld (dat wil zeggen dat geen enkele thread de vergrendeling in bezit heeft). Voor een nestbare vergrendeling is het eerste aantal nesten nul. Het is niet compatibel om een van deze routines aan te roepen met een vergrendelingsvariabele die al is geïnitialiseerd.

3.2.2 de functies omp_destroy_lock en omp_destroy_nest_lock

Deze functies zorgen ervoor dat de verwijzende vergrendelingsvariabele lock niet is geïnitialiseerd. De indeling is als volgt:

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

Het is niet-compatibel om een van deze routines aan te roepen met een vergrendelingsvariabele die niet-geïnitialiseerd of ontgrendeld is.

3.2.3 functies omp_set_lock en omp_set_nest_lock

Elk van deze functies blokkeert de thread die de functie uitvoert totdat de opgegeven vergrendeling beschikbaar is en stelt vervolgens de vergrendeling in. Er is een eenvoudige vergrendeling beschikbaar als deze is ontgrendeld. Een nestbare vergrendeling is beschikbaar als deze ontgrendeld is of als deze al eigendom is van de thread die de functie uitvoert. De indeling is als volgt:

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

Voor een eenvoudige vergrendeling moet het argument naar de omp_set_lock functie verwijzen naar een geïnitialiseerde vergrendelingsvariabele. Het eigendom van de vergrendeling wordt verleend aan de thread die de functie uitvoert.

Voor een nestbare vergrendeling moet het argument voor de omp_set_nest_lock-functie verwijzen naar een geïnitialiseerde vergrendelingsvariabele. De nesttelling wordt verhoogd en de thread krijgt of behoudt eigendom over de lock.

3.2.4 omp_unset_lock en omp_unset_nest_lock functies

Deze functies bieden de middelen om het eigendom van een vergrendeling los te laten. De indeling is als volgt:

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

Het argument voor elk van deze functies moet verwijzen naar een geïnitialiseerde vergrendelingsvariabele die eigendom is van de thread die de functie uitvoert. Het gedrag is niet gedefinieerd als de thread niet eigenaar is van die vergrendeling.

Voor een eenvoudige vergrendeling ontkoppelt de omp_unset_lock functie de thread die de functie uitvoert van de controle over de vergrendeling.

Voor een nestbare vergrendeling wordt met de omp_unset_nest_lock functie het aantal nesten afgerekend en wordt de thread die de functie uitvoert van het eigendom van de vergrendeling vrijgegeven als het resulterende aantal nul is.

3.2.5 omp_test_lock en omp_test_nest_lock functies

Met deze functies wordt geprobeerd een vergrendeling in te stellen, maar de uitvoering van de thread niet te blokkeren. De indeling is als volgt:

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

Het argument moet verwijzen naar een geïnitialiseerde vergrendelingsvariabele. Deze functies proberen een vergrendeling op dezelfde manier in te stellen als omp_set_lock en omp_set_nest_lock, behalve dat ze de uitvoering van de thread niet blokkeren.

Voor een eenvoudige vergrendeling retourneert de omp_test_lock functie een niet-nulwaarde als de vergrendeling is ingesteld. Anders wordt nul geretourneerd.

Voor een nestbare vergrendeling retourneert de omp_test_nest_lock functie het nieuwe aantal nesten als de vergrendeling is ingesteld. Anders wordt nul geretourneerd.

3.3 Tijdsroutines

De functies die in deze sectie worden beschreven, ondersteunen een draagbare wandkloktimer:

3.3.1 functie omp_get_wtime

De omp_get_wtime functie retourneert een drijvende-kommawaarde met dubbele precisie die gelijk is aan de verstreken tijd in seconden sinds een bepaald moment in het verleden. De werkelijke 'tijd in het verleden' is willekeurig, maar het is gegarandeerd niet te veranderen tijdens de uitvoering van het toepassingsprogramma. De indeling is als volgt:

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

Er wordt verwacht dat de functie wordt gebruikt om verstreken tijden te meten, zoals wordt weergegeven in het volgende voorbeeld:

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);

De geretourneerde tijden zijn 'tijden per thread'. Dit betekent dat ze niet globaal consistent hoeven te zijn voor alle threads die deelnemen aan een toepassing.

3.3.2 omp_get_wtick functie

De omp_get_wtick functie retourneert een drijvende kommawaarde met dubbele precisie die gelijk is aan het aantal seconden tussen opeenvolgende kloktekens. De indeling is als volgt:

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