Skoči na vsebino

OpenCL1

Do sedaj smo spoznali, kako je zgrajena GPE, kaj so računske enote in procesni elementi, kako se programi na njej izvajajo, kako se razvrščajo delovne skupine in niti in kakšna je pomnilniška hierarhija GPE. Sedaj je čas, da pogledamo, kakšen je programski model.

Ogrodje OpenCL

OpenCL (Open Computing Language) je odprtokodno ogrodje, namenjeno vzporednemu programiranju širokega spektra heterogenih sistemov. OpenCL vsebuje programski jezik OpenCL C, namenjen pisanju programske kode, ki se bo izvajala na napravah (na primer GPE ali FPGA). Že prej smo spoznali, da takim programom pravimo ščepci (ang. kernels). Isti ščepec izvajajo vse niti na GPE. Na žalost ima OpenCL eno veliko pomanjkljivost: ni lahek za učenje. Zato moramo, preden lahko spišemo svoj prvi program v OpenCL, spoznati nekaj pomembnih konceptov.

Platforma in naprave

OpenCL vidi nek splošen heterogen sistem kot platformo, sestavljeno iz gostitelja (ang. host) in ene ali več različnih naprav (ang. devices). Naprave so običajno pospeševalniki GPE ali FPGA. Platformo prikazuje spodnja slika.

Platforma

Vsak program v OpenCL je sestavljen iz dveh glavnih delov:

  • kode, ki se izvaja na gostitelju (ang. host program) in
  • enega ali več ščepcev (ang. kernel), ki se izvajajo na napravi.

Izvajalni model OpenCL

Prej smo že spoznali izvajalni model GPE. Spoznali smo računske enote (CU) in procesne elemente (PE) ter niti in skupine niti. OpenCL uporablja podobno abstrakcijo - ščepec hkrati izvaja veliko število niti. Le-te so grupirane v delovne skupine. Niti v delovnih skupinah si lahko izmenjujeo podatke preko lokalnega pomnilnika in se lahko medseboj sinhronizirajo.

Vsaka nit ima svoj enoličen identifikator (ID). Načeloma so ID-ji niti eno-, dvo- ali tri-dimenzionalni in podani s celimi števili. Za potrebe čimbolj razumljive razlage, se bomo v nadaljevanju omejili le na dve dimenziji. Indeksiranje niti vedno prilagajamo prostorski organizaciji podatkov. Na primer, če so naši podatki vektorji, bomo niti indeksirali v eni dimenziji, če pa so naši podatki matrike ali slike, bomo niti indeksirali v dveh dimezijah. Tako nam OpenCL omogoča, da tudi niti prostorsko organiziramo na enak način kot podatke. S tem bodo na primer pri slikah indeksi niti sovpadali z indeksi (koordinatami) slikovnih točk. V terminologiji OpenCL pravimo prostoru niti NDRange. Prav tako v prostoru niti eno-, dvo- ali tri-dimenzionalno indeksiramo tudi delovne skupine. Primer dvo-dimezionalnega indeksiranja prikazuje spodnja slika.

NDRange

Vsaka nit v 2D prostoru NDRange ima dva para indeksov:

  • globalni indeks (globalni ID) in
  • lokalni indeks (lokalni ID).

Globalni indeks označuje indeks niti v celotnem prostoru niti NDRange, medtem ko lokalni indeks niti označuje njen položaj znotraj delovne skupine. Na zgornji sliki prostor niti NDRange vsebuje 16 x 16 = 256 niti v 4 delovnih skupinah. Vsaka skupina pa ima 8x8 = 64 niti. Globalni indeks vsake niti je določen s parom (gy, gx), kjer gy označuje indeks v vertikalni smeri (torej vrstico) in gx označuje indeks v horizontalni smeri (torej stolpec). Koordinata (0,0) je vedno v zgornjem levem kotu. Prav tako je lokalni indeks vseh niti določen s parom (ly, lx). Za primer si poglejmo nit, označeno z zeleno barvo. Njen globalni indeks je (12,10), medtem ko je njen lokalni indeks (4,2). Indeks posamezne delovne skupine niti je določen s parom (wy,wx). Vsak prostor niti NDRange ima svoje dimenzije, ki povedo, koliko niti ali skupin niti ga sestavlja. Globalna dimenzija prostora NDRange na zgornji sliki je določena s parom (GY,GX) in je (16,16), medtem ko je lokalna dimenzija posamezne skupine določena s parom (LY,LX) in je (8,8). Globalna dimenzija prostora niti NDRange se lahko meri tudi v delovnih skupinah niti in je na zgornji sliki določena s parom (WY,WX) in je (2,2).

OpenCL vsebuje vgrajene funkcije za ugotavljanje dimenzij prostora NDRange ter za ugotavljanje posameznih indeksov niti, ki so prikazane v spodnji tabeli.

Funkcija Pomen
get_work_dim število dimenzij v prostoru niti NDRange
get_global_size število niti v prostoru niti
get_global_id globalni indeks niti
get_local_size število niti v delovni skupini
get_local_id lokalni indeks niti
get_num_groups število delovnih skupin
get_group_id indeks delovne skupine

OpenCL pomnilniški model

OpenCL vsebuje abstrakcijo pomnilniške hierarhije na GPE, ki jo prikazuje spodnja slika.

Abstrakcija pomnilnikov

Pomnilniki, ki jih predvideva OpenCL so:

  • V privatnem pomnilniku (ang. private memory) hranimo spremenljivke, ki bodo privatne za vsako nit. V GPE privatni pomnilnik predstavljajo registri računskih elementov. Če želimo, da je neka spremenljivka privatna za nit, potem jo moramo deklarirati z dopolnilom __private. V OpenCL so vse spremenljivke privzeto privatne in dopolnila ni potrebno navajati.

  • V lokalnem pomnilniku (ang. local mamory) hranimo spremenljivke, za katere želimo, da so vidne vsem nitim v isti delovni skupini. Če želimo, da se neka spremenljivka hrani v lokalnem pomnilniku, ji ob deklaraciji dodamo dopolnilo __local.

  • V globalnem pomnilniku (ang. global memory) hranimo spremenljivke, za katere želimo, da so vidne vsem nitim iz vseh delovnih skupin v prostoru niti NDRange. Če želimo, da se neka spremenljivka hrani v globalnem pomnilniku, jo moramo deklarirati z dopolnilom __global.

  • Pomnilnik konstant (ang. constant memory) je del globalnega pomnilnika, ki se med izvajanjem ne spreminja. Če želimo, da se neka konstanta hrani v globalnem pomnilniku, ob deklaraciji uporabimo dopolnilo __constant.




  1. © Patricio Bulić, Univerza v Ljubljani, Fakulteta za računalništvo in informatiko. Gradivo je objavljeno pod licenco Creative Commons Priznanje avtorstva-Nekomercialno-Deljenje pod enakimi pogoji 4.0 Mednarodna