OpenHMPP Open Standard (HMPP tarkoittaa Hybrid Multicore Parallel Programming ) on ohjeperusteinen ohjelmointimalli, joka on suunniteltu manipuloimaan laitteistokiihdyttimiä huolimatta GPU- ohjelmoinnin monimutkaisuudesta . Tämän mallin toteutus valittiin direktiivien perusteella, koska ne mahdollistavat löyhän suhteen sovelluskoodin ja laitteistokiihdyttimien käytön välillä .
HUOM : Tämä artikkeli kattaa OpenHMPP-direktiivit, jotka muodostavat avoimen standardin, mutta ei käsittele direktiivien täytäntöönpanoa, joka liittyy direktiivien täytäntöönpanoon.
OpenHMPP-mallin syntaksi mahdollistaa laskelmien tehokkaan jakamisen laitteistokiihdyttimille ja optimoida datan liikkumisen laitteiston muistiin / muistiin.
Malli perustuu CAPS (Compiler and Architecture for Embedded and Superscalar Processors) -hankkeeseen, jonka toteuttivat yhdessä INRIA, CNRS, Rennesin yliopisto 1 ja INSA Rennes.
OpenHMPP-standardi perustuu koodelin käsitteeseen, joka on toiminto, joka voidaan suorittaa etänä laitteistolle.
Koodeletilla on seuraavat ominaisuudet:
Nämä ominaisuudet varmistavat, että RPC-koodekki voidaan suorittaa etänä laitteistolla. Tämä RPC-kutsu ja siihen liittyvät tiedonsiirrot voivat olla asynkronisia.
OpenHMPP tarjoaa synkronisen ja asynkronisen etäkäytön kutsuprotokollan .
Asynkronisen toiminnan toteutus riippuu laitteistosta.
OpenHMPP ottaa huomioon kaksi osoiteavaruutta:
OpenHMPP-direktiivit voidaan nähdä ”metatiedoina”, jotka lisätään sovelluksen lähdekoodiin. Siksi se on vaaraton metatieto eli se ei muuta koodin alkuperäistä käyttäytymistä.
Ne käsittelevät toiminnon etäsuoritusta (RPC) sekä tiedonsiirtoa laitteiston muistista / laitteiston muistiin. Seuraava taulukko esittelee OpenHMPP-direktiivit, jotka on luokiteltu vastaamaan tarpeita: jotkut on omistettu julistuksille, toiset omistettu suorituksenhallinnalle.
Virtauksen säätöohjeet | Tiedonhallinnan ohjeet | |
---|---|---|
Lausunnot | koodeliryhmä | asukas kartta mapbyname |
Toimintaohjeet | puhelupaikan synkronointialue | varaa julkaisun lisäkuormitus delegoitu kauppa |
Yksi OpenHMPP-mallin ehdottaman lähestymistavan keskeisistä kohdista on direktiivien käsite, joka liittyy etiketteihin, joiden avulla voidaan luoda yhtenäinen rakenne kaikille sovellussarjaan levitetyille direktiiveille.
Tarroja on kahta tyyppiä:
Merkintöjen yksinkertaistamiseksi säännöllisiä lausekkeita käytetään kuvaamaan OpenHMPP-direktiivien syntaksia.
Seuraavia värikäytäntöjä käytetään myös:
OpenHMPP-direktiivien yleinen syntaksi on:
tai:
Direktiiviin liittyvillä parametreilla voi olla useita tyyppejä.
Seuraavaksi OpenHMPP: llä määritetyt parametrit:
Direktiivissä codeletmääritetään, että seuraavan toiminnon versio tulisi optimoida määritetylle laitteistolle.
Direktiivin osalta codelet :
Direktiivin syntaksi on:
#pragma hmpp <grp_label> codelet_label codelet [, version = major.minor[.micro]?]? [, args[arg_items].io=[[in|out|inout]]* [, args[arg_items].size={dimsize[,dimsize]*}]* [, args[arg_items].const=true]* [, cond = "expr"] [, target=target_name[:target_name]*]codeletTietylle toiminnolle voi olla useita direktiivejä , joista kukin määrittelee eri käyttötarkoitukset tai erilaiset suoritusyhteydet. Annetulle callsiteetiketille voi kuitenkin olla vain yksi direktiivi codelet.
Direktiivissä callsitemääritetään koodeksin käyttö tietyssä ohjelman kohdassa.
Direktiivin syntaksi on:
#pragma hmpp <grp_label> codelet_label callsite [, asynchronous]? [, args[arg_items].size={dimsize[,dimsize]*}]* [, args[arg_items].advancedload=[[true|false]]* [, args[arg_items].addr="expr"]* [, args[arg_items].noupdate=true]*Seuraava esimerkki:
/* déclaration du codelet */ #pragma hmpp simple1 codelet, args[outv].io=inout, target=CUDA static void matvec(int sn, int sm, loat inv[sm], float inm[sn][sm], float *outv){ int i, j; for (i = 0 ; i < sm ; i++) { float temp = outv[i]; for (j = 0 ; j < sn ; j++) { temp += inv[j] * inm[i][ j]; } outv[i] = temp; } int main(int argc, char **argv) { int n; ........ /* Utilisation du codelet */ #pragma hmpp simple1 callsite, args[outv].size={n} matvec(n, m, myinc, inm, myoutv); ........ }Joissakin tapauksissa erityinen tiedonhallinta on tarpeen sovelluksessa (tiedonsiirron optimointi suorittimen ja näytönohjaimen välillä, jaetut muuttujat jne.).
Direktiivi groupsallii koodekeryhmän ilmoittamisen. Tälle direktiiville määriteltyjä parametreja sovelletaan kaikkiin tähän ryhmään liittyviin koodekseihin.
Direktiivin syntaksi on:
#pragma hmpp <grp_label> group [, version = <major>.<minor>[.<micro>]?]? [, target = target_name[:target_name]*]? [, cond = “expr”]?HWA: n käytön tärkein pullonkaula on usein tiedonsiirto laitteiston ja pääprosessorin välillä.
Viestintään liittyvien lisäkustannusten rajoittamiseksi tiedonsiirto voi olla yhteistä saman koodelin peräkkäisille suorituksille käyttäen laitteen asynkronista ominaisuutta.
Se lukitsee laitteiston ja jakaa tarvittavan määrän muistia.
#pragma hmpp <grp_label> allocate [,args[arg_items].size={dimsize[,dimsize]*}]*Siinä määritetään, milloin materiaali tulisi vapauttaa ryhmälle tai erilliselle koodetille.
#pragma hmpp <grp_label> releaseSe lataa tiedot ennen koodellin etäsuorittamista.
Se muodostaa synkronisen esteen, jonka avulla voidaan sitten odottaa asynkronisen koodelin suorittamisen loppuun saattamista ennen tulosten lataamista.
Direktiivissä synchronizemääritetään, että sinun on odotettava .synkronista suoritusta callsite.
Tässä direktiivissä pakkausselosteet ovat aina pakollisia ja tunniste groupvaaditaan, jos koodelit on liitetty ryhmään. Direktiivin syntaksi on:
Seuraavassa esimerkissä laitteiston alustus, muistin allokointi ja tulodatan lataus suoritetaan kerran silmukan ulkopuolella sen sijaan, että ne suoritettaisiin silmukan jokaisella iteroinnilla.
Direktiivin synchronizeavulla voit odottaa koodelin asynkronisen suorituksen loppua ennen uuden iteroinnin aloittamista. Lopuksi delegatedstoresilmukan ulkopuolelle asetettu direktiivi lataa "sgemm" -tuloksen.
int main(int argc, char **argv) { #pragma hmpp sgemm allocate, args[vin1;vin2;vout].size={size,size} #pragma hmpp sgemm advancedload, args[vin1;vin2;vout], args[m,n,k,alpha,beta] for ( j = 0 ; j < 2 ; j ++) { #pragma hmpp sgemm callsite, asynchronous, args[vin1;vin2;vout].advancedload=true, args[m,n,k,alpha,beta].advancedload=true sgemm (size, size, size, alpha, vin1, vin2, beta, vout); #pragma hmpp sgemm synchronize } #pragma hmpp sgemm delegatedstore, args[vout] #pragma hmpp sgemm release
Nämä direktiivit mahdollistavat kaikkien argumenttien, joilla on sama nimi, jakamisen koko ryhmälle.
Kaikkien jaettujen argumenttien tyyppien ja ulottuvuuksien on oltava samat.
Direktiivin mapavulla voidaan liittää useita argumentteja laitteistoon.
#pragma hmpp <grp_label> map, args[arg_items]Direktiivi mapbynameon samanlainen kuin direktiivi, mappaitsi että kartoitettavat argumentit määritetään suoraan nimellä. Direktiivi mapbynamevastaa useita direktiivejä map.
Merkinnät ovat seuraavat:
#pragma hmpp <grp_label> mapbyname [,variableName]+Direktiivi residentjulistaa muuttujat globaaleiksi ryhmän sisällä.
Näihin muuttujiin pääsee suoraan mistä tahansa ryhmän laitteistosta laitteistossa (niitä pidetään tavallaan laitteiston "asukkaina").
Tätä direktiiviä sovelletaan ilmoitukseen, joka seuraa sitä lähdekoodissa.
Tämän direktiivin syntaksi on:
#pragma hmpp <grp_label> resident [, args[::var_name].io=[[in|out|inout]]* [, args[::var_name].size={dimsize[,dimsize]*}]* [, args[::var_name].addr="expr"]* [, args[::var_name].const=true]*Merkintä ::var_nameetuliitteellä ::osoittaa sovelluksen muuttujan, joka on ilmoitettu nimellä resident.
Alue on sekoitus koodekki- / puhelupalveludirektiivejä. Sen tavoitteena on välttää koodin uudelleenjärjestely, joka johtuu nimenomaisesta koodisarjojen luomisesta. Siksi kaikki direktiiveihin käytettävissä olevat attribuutit codelettai callsiteniitä voidaan käyttää direktiivissä region.
Syntaksi on seuraava:
#pragma hmpp [<MyGroup>] [label] region [, args[arg_items].io=[[in|out|inout]]* [, cond = "expr"]< [, args[arg_items].const=true]* [, target=target_name[:target_name]*] [, args[arg_items].size={dimsize[,dimsize]*}]* [, args[arg_items].advancedload=[[true|false]]* [, args[arg_items].addr="expr"]* [, args[arg_items].noupdate=true]* [, asynchronous]? [, private=[arg_items]]* { C BLOCK STATEMENTS }OpenHMPP perustuu HMPP: n versioon 2.3 (Toukokuu 2009, CAPS-yritys).
OpenHMPP: n ehdottaman mallin toteuttaa:
Lisäksi OpenHMPP: tä käytetään HPC- hankkeiden puitteissa muun muassa öljy-, energia-, teollisuus-, koulutus- ja tutkimusalueilla, ja sen avulla voidaan kehittää sovellusten korkean suorituskyvyn versioita säilyttäen jo tuotettu koodi.