OpenHMPP Açık Standart (HMPP, Hibrit Çok Çekirdekli Paralel Programlama anlamına gelir ), donanım hızlandırıcılarını GPU programlamayla ilişkili karmaşıklık konusunda endişelenmeden yönetmek için tasarlanmış, kılavuz tabanlı bir programlama modelidir . Bu model için uygulama seçimi, uygulama kodu ile donanım hızlandırıcılarının kullanımı arasında gevşek bir ilişkiye izin verdikleri için direktiflere düştü .
Not : Bu makale, Açık Standardı oluşturan OpenHMPP direktiflerini kapsar, ancak direktiflerin uygulanmasıyla bağlantılı direktiflerin uygulanmasıyla ilgilenmez.
OpenHMPP modeli tarafından sunulan sözdizimi, hesaplamaların donanım hızlandırıcıları üzerinde verimli bir şekilde dağıtılmasını ve donanımın belleğinden / belleğine veri hareketlerinin optimize edilmesini mümkün kılar.
Model INRIA, CNRS, University of Rennes 1 ve INSA of Rennes tarafından ortaklaşa yürütülen CAPS (Compiler and Architecture for Embedded and Superscalar Processors) projesine dayanmaktadır.
OpenHMPP standardı, donanım üzerinde uzaktan gerçekleştirilebilen bir işlev olan kod hücresi kavramına dayanmaktadır.
Bir kod hücresi aşağıdaki özelliklere sahiptir:
Bu özellikler, bir RPC kod hücresinin donanım tarafından uzaktan çalıştırılabilmesini sağlar. Bu RPC çağrısı ve ilişkili veri aktarımları zaman uyumsuz olabilir.
OpenHMPP, senkronize ve asenkron uzaktan prosedür çağrısı protokolü sağlar .
Eşzamansız işlem uygulaması donanıma bağlıdır.
OpenHMPP iki adres alanını hesaba katar:
OpenHMPP direktifleri, uygulamanın kaynak koduna eklenen “meta bilgi” olarak görülebilir. Bu nedenle zararsız bir meta bilgidir, yani kodun orijinal davranışını değiştirmez.
Donanım belleğinden / belleğine veri aktarımlarının yanı sıra işlevin uzaktan yürütülmesini (RPC) ele alırlar. Aşağıdaki tablo, ele alınan ihtiyaca göre sınıflandırılan OpenHMPP direktiflerini tanıtmaktadır: bazıları bildirimlere, diğerleri ise yürütme yönetimine adanmıştır.
Akış kontrol talimatları | Veri yönetimi için yönergeler | |
---|---|---|
İfadeler | codelet grubu | yerleşik harita mapbyname |
Operasyonel direktifler | çağrı sitesi eşitleme bölgesi | yayın gelişmiş yük delegatedstore ayır |
OpenHMPP modeli tarafından önerilen yaklaşımın temel noktalarından biri, uygulamada yayılan tüm bir direktif seti için tutarlı bir yapı kurmayı mümkün kılan etiketlerle ilişkili direktifler kavramıdır.
İki tür etiket vardır:
Gösterimleri basitleştirmek için, OpenHMPP direktiflerinin sözdizimini açıklamak için düzenli ifadeler kullanılacaktır.
Aşağıdaki renk kuralları da kullanılacaktır:
OpenHMPP direktiflerinin genel sözdizimi şöyledir:
veya:
Bir direktifle ilişkili parametrelerin birkaç türü olabilir.
Takip etmek için, OpenHMPP ile tanımlanan parametreler:
Bir yönerge codelet, aşağıdaki işlevin bir sürümünün belirli bir donanım için optimize edilmesi gerektiğini belirtir.
Yönerge için codelet :
Yönergenin sözdizimi şöyledir:
#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]*]codeletBelirli bir işlev için, her biri farklı kullanımları veya farklı yürütme bağlamlarını belirten birden çok yönergeye sahip olmak mümkündür . Ancak, belirli bir callsiteetiket için yalnızca bir yönerge olabilir codelet.
Yönerge callsite, programın belirli bir noktasında kod hücresinin kullanımını belirtir.
Yönergenin sözdizimi şöyledir:
#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]*İzlenecek bir örnek:
/* 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); ........ }Bazı durumlarda, uygulamada özel veri yönetimi gereklidir (CPU ile GPU arasındaki veri hareketlerinin optimizasyonu, paylaşılan değişkenler vb.).
Yönerge group, bir grup kod hücresinin bildirimine izin verir. Bu yönerge için tanımlanan parametreler, bu grupla ilişkili tüm kod hücrelerine uygulanır.
Yönergenin sözdizimi şöyledir:
#pragma hmpp <grp_label> group [, version = <major>.<minor>[.<micro>]?]? [, target = target_name[:target_name]*]? [, cond = “expr”]?HWA kullanırken ana darboğaz, genellikle donanım ve ana işlemci arasındaki veri aktarımlarıdır.
İletişimle bağlantılı ek maliyetleri sınırlamak için, veri transferleri, ekipmanın asenkron özelliği kullanılarak aynı kod hücresinin birbirini izleyen yürütmelerinde ortak olabilir.
Donanımı kilitler ve gerekli miktarda belleği tahsis eder.
#pragma hmpp <grp_label> allocate [,args[arg_items].size={dimsize[,dimsize]*}]*Materyalin bir grup veya bağımsız bir kod hücresi için ne zaman serbest bırakılması gerektiğini belirtir.
#pragma hmpp <grp_label> releaseKod hücresinin uzaktan yürütülmesinden önce verileri yükler.
Bir eşzamansız kod hücresinin yürütülmesinin tamamlanmasını ve ardından sonuçları indirmeden önce beklemeyi mümkün kılan eşzamanlı bir bariyer oluşturur.
Yönergesi synchronizesen eşzamansız olarak yürütülmesi için beklemelisiniz belirtir callsite.
Bu yönerge için kod hücresi etiketi her zaman zorunludur ve groupkod hücresi bir grupla ilişkilendirilmişse etiket gereklidir. Yönergenin sözdizimi şöyledir:
Aşağıdaki örnekte, donanım başlatma, bellek tahsisi ve girdi verilerinin indirilmesi, döngünün her yinelemesinde gerçekleştirilmek yerine döngü dışında bir kez gerçekleştirilir.
Yönerge synchronize, başka bir yinelemeye başlamadan önce kod hücresinin eşzamansız yürütülmesinin sonunu beklemenize izin verir. Son olarak, delegatedstoredöngünün dışına yerleştirilen yönerge "sgemm" çıktısını indirir.
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
Bu yönergeler, bütün bir grup için aynı ada sahip tüm argümanların paylaşılmasını mümkün kılar.
Tüm paylaşılan argümanların türleri ve boyutları aynı olmalıdır.
Yönerge map, donanım üzerinde birkaç argümanın ilişkilendirilmesine izin verir.
#pragma hmpp <grp_label> map, args[arg_items]Yönerge mapbyname, mapeşlenecek bağımsız değişkenlerin doğrudan adla belirtilmesi dışında yönergeye benzer . Yönerge mapbyname, birden çok yönergeye eşdeğerdir map.
Gösterim aşağıdaki gibidir:
#pragma hmpp <grp_label> mapbyname [,variableName]+Yönerge resident, bir grup içinde değişkenleri global olarak bildirir.
Bu değişkenlere donanım üzerindeki grubun herhangi bir kod hücresinden doğrudan erişilebilir (bir şekilde donanım üzerinde "yerleşik" olarak kabul edilirler).
Bu yönerge, kaynak kodunda onu izleyen bildirim için geçerlidir.
Bu direktifin sözdizimi şöyledir:
#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]*Ön ::var_nameekli gösterim , ::olarak bildirilen bir uygulama değişkenini gösterir resident.
Bölge, codelet / çağrı sitesi yönergelerinin bir karışımıdır. Amacı, kod hücrelerinin açık bir şekilde oluşturulmasıyla empoze edilen kodun yeniden yapılandırılmasından kaçınmaktır. Bu nedenle, direktifler için mevcut olan tüm nitelikler codeletveya direktif callsiteiçin kullanılabilir region.
Sözdizimi aşağıdaki gibidir:
#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, HMPP'nin 2.3 sürümüne (Mayıs 2009, CAPS şirketi).
OpenHMPP tarafından önerilen model şu şekilde uygulanmaktadır:
Ayrıca OpenHMPP, petrol, enerji, endüstri, eğitim ve araştırma gibi alanlarda yürütülen HPC projeleri çerçevesinde kullanılmakta ve halihazırda üretilen kodu korurken uygulamalarının yüksek performanslı versiyonlarının geliştirilmesine olanak sağlamaktadır.