GPGPU: laagdrempelige hardware voor zware berekeningen

Als de rekentijd voor jouw applicatie een probleem is, dan is een general-purpose graphics processing unit (GPGPU) misschien een oplossing. GPGPU’s kunnen berekeningen soms een ordegrootte versnellen. Een extra voordeel is dat ze per berekening veel minder vermogen gebruiken. Maar het is niet altijd eenvoudig om hun kracht te benutten en het werkt alleen voor toepassingen die aan specifieke eisen voldoen.

Wat is een GPGPU?

Een GPGPU is een breder inzetbare vorm van een Graphics Processing Unit (GPU). Dat is een processor die oorspronkelijk was bedacht voor grafische taken. Waar de gewone processor in een PC ontworpen is om een brede set aan taken te doen, zijn GPU’s speciaal ontworpen voor grafische algoritmen. De essentiële truc is dat zulke algoritmes een hoge mate van parallellisme hebben. Daarom bestaat een GPU uit veel kleine processoren die de grafische berekeningen parallel uitvoeren.

Maar behalve grafische algoritmen zijn er nog andere soorten algoritmen die veel parallellisme hebben. Veel zware rekentaken, zoals weersvoorspellingen en sterkteberekeningen, zijn gebaseerd op het manipuleren van grote matrices en vectoren. Ook dat werkt goed op een GPU. Daarom is het niet verrassend dat GPU’s belangrijk geworden zijn voor grootschalige berekeningen.

Om GPU’s geschikt te maken voor algemene, niet-grafische algoritmes is een meer generieke programmeer interface ontwikkeld. Op zijn beurt heeft dit ertoe geleid dat de hardware geoptimaliseerd werd om die meer generieke taken uit te voeren. Daarmee werd de GPU een General Purpose GPU, ofwel een GPGPU. Zo ondersteunen sommige GPGPU’s tegenwoordig berekeningen in dubbele precisie, wat voor grafische berekeningen niet nodig is.

De hardware

Het aantal processors in een GPGPU kan oplopen tot  meer dan 10.000 op high-end GPU’s. Maar het is belangrijk om te bedenken dat deze processoren niet onafhankelijk zijn: ze voeren tegelijk dezelfde instructie uit maar op verschillende data-elementen. Met andere woorden: het is een data-parallelle berekening en niet taak-parallel.

Minsten zo belangrijk als het aantal processoren is het geheugen van de GPGPU. Meestal is dat redelijk beperkt tot enkele tientallen Gigabytes. Het geheugen is dan ook vooral geoptimaliseerd voor een hoge doorvoer in plaats van voor de opslag van grote hoeveelheden data. Het idee is dat de data alleen op de GPGPU aanwezig is als er daadwerkelijk mee gewerkt wordt.

Leveranciers

Op dit moment zijn er eigenlijk maar drie leveranciers van GPGPU’s. De marktleider is Nvidia, met een marktaandeel van zo’n 80%. AMD is tweede met 17% van de markt en het kleine restant is voor Intel. In de afgelopen jaren is de vraag naar GPGPU’s enorm toegenomen, vooral door de ontwikkelingen op het gebied van AI waarvoor ze ook heel geschikt zijn. Leveranciers hebben moeite om aan de vraag te voldoen en dat leidt tot lange levertijden en hoge prijzen voor de topmodellen. Een uitweg kan zijn om GPGPU’s te gebruiken die in de Cloud worden aangeboden. Zie bijvoorbeeld hoe dit werkt op Azure.

Programmeren voor GPGPU’s

Er zijn verschillende opties om GPGPU’s te programmeren. De meest gebruikte is CUDA, wat geleverd wordt door Nvidia. De populariteit ervan is duidelijk gekoppeld aan de populariteit van Nvidia GPGPU’s. CUDA is in wezen een uitbreiding van C++: extra programmeerconstructies en keywords in een C++ programma zorgen ervoor dat een deel van de code op de GPGPU wordt uitgevoerd. Er bestaat een soortgelijke uitbreiding voor Fortran.

De tweede Populaire optie is OpenCL, wat leverancier-onafhankelijk is. Dat klinkt mooi maar het is belangrijk om te beseffen dat CUDA een product is van Nvidia en daarom helemaal toegesneden is op hun GPGPU’s. Dus OpenCL is alleen een goede optie als het daadwerkelijk de bedoeling is dat er GPGPU’s van verschillende leveranciers gebruikt gaan worden.

Vaak moet voor een goede performance gebruik gemaakt worden van verschillende niveaus van parallellisme: van het lage-niveau parallellisme dat GPGPU’s leveren naar taak-parallellisme op bijvoorbeeld multicore CPU’s. In dat geval wordt CUDA or OpenCL vaak gecombineerd met een hoger-niveau framework zoals OpenMP of MPI. Dit kan ook gebruikt worden om code op meerdere GPGPU’s tegelijk uit te voeren, waarbij ook de beperkingen in het geheugen van een GPGPU soms omzeild kunnen worden.

Een elegante manier om af te komen van de leveranciersafhankelijkheid en de issues met verschillende niveaus van parallellisme is door het gebruik van frameworks zoals OCCA en Kokkos. Dit zijn application programming interfaces (APIs) waarmee parallellisme op een generieke manier kan worden uitgedrukt, waarna een compiler code genereert voor de beschikbare hardware. Vaak levert dit platform-onafhankelijke programmatuur die redelijk goed presteert op verschillende GPGPU’s. Maar het zal in principe wel minder goed presteren dan een zwaar geoptimaliseerde kernel die direct met CUDA is geprogrammeerd.

Werkt het voor jouw toepassing?

Of een GPGPU een oplossing is voor jouw problemen met rekentijd hangt heel erg af van de toepassing. Ten eerste werkt het alleen als de rekentijd gedomineerd wordt door berekeningen die in hoge mate data-parallel zijn. Als de toepassing bijvoorbeeld de helft van de rekentijd besteed aan berekeningen die niet parallel zijn, dan krijg je nooit meer dan een factor twee versnelling, zelfs niet als de parallelle helft helemaal geen rekentijd meer zou vergen. Als je een factor tien versnelling wilt dan moet tenminste 90% van de rekentijd geparallelliseerd kunnen worden.

Een tweede aspect dat van belang is voor de versnelling die verwacht kan worden is de mate waarin de data heen en weer moet bewegen tussen het centrale geheugen en het geheugen van de GPGPU. Als er te veel met de data geschoven moet worden dan zal dat leiden tot een lagere performance. Idealiter vindt het transport van data alleen plaats aan het begin en eind van een grote berekening en worden alle tussenliggende berekeningen uitgevoerd vanuit het geheugen van de GPGPU.

Hoewel dit vrij eenvoudige richtlijnen zijn, is het vaak moeilijk in te schatten wat een GPGPU voor de performance doet. Delen van de applicatie die oorspronkelijk niet parallel zijn kunnen misschien worden vervangen door andere algoritmen. Het kan nuttig zijn om stukken code te vervangen dor aanroepen van softwarebibliotheken die geoptimaliseerd zijn voor GPGPU, zoals cuBLAS. En soms kan het geheugengebruik verbeterd worden door berekeningen anders te organiseren. Kortom: enige aanpassingen aan de code kunnen tot een enorme verbetering in GPGPU-performance leiden. Bij VORtech helpen we onze klanten hierbij in de vorm van advies en softwareontwikkeling. Onderaan deze blog geven we daar meer informatie over.

Voorbeelden

Het meeste werk dat we voor onze klanten doen is vertrouwelijk en daarom kunnen we geen details delen over het werk aan GPGPU’s dat we doen. Maar er staan veel indrukwekkende voorbeelden van GPGPU-toepassingen op internet. Hier zijn er een paar.

Op het gebied van biotechnologie, is deze commerciële brochure van Nvidia de moeite van het bekijken waard. Het toont de performanceverbeteringen voor verschillende biotech toepassingen bij gebruik van een of meerdere GPGPU’s. Die verbeteringen variëren flink tussen de verschillende toepassingen. Voor de meeste is het minder dan een factor tien maar er is ook een toepassing waarbij de rekentijd van 3,5 dagen teruggebracht wordt tot vier uur.

Een andere toepassing die veel berekeningen vergt is numerieke weersvoorspelling. In dit artikel is een goede discussie te vinden van de voor- en nadelen. De afname in rekentijd is niet per se indrukwekkend (ongeveer een factor vier) maar het voordeel zit ‘m in het feit dat dezelfde rekentijd nog maar een kwart van de hoeveelheid hardware vraagt. Het levert dus een kostenbesparing op, zowel ten aanzien van hardware-beheer als ten aanzien van energiegebruik.

Een ander commercieel article, van Ansys Fluent, laat indrukwekkende resultaten zien voor de snelheid van een aerodynamische berekening, die 32 keer sneller draait dan op een multicore processor die zelf al best krachtig is. Ook hier is het energiegebruik van de GPGPU’s weer veel minder dan dat van een systeem op basis van CPU’s.

Tenslotte bieden de meeste bekende eindige-elementenpakketten ook de mogelijkheid om GPGPU’s te gebruiken. Abaqus meldt bijvoorbeeld een versnelling van een factor vier voor een model van 3 miljoen roosterpunten en 10 miljoen vrijheidsgraden.

Kunnen we u helpen om de kracht van GPGPU’s te gebruiken?

Een van onze kerncompetenties als bedrijf is het versnellen van rekentoepassingen voor onze klanten. Daarvoor bieden we een scala aan expertise, van performance-aware programmeren via efficiënte algoritmen tot het volledig parallelliseren voor een high-performance computingsysteem. Dit alles doen we in nauwe samenwerking met de ontwikkelaars van de klant zodat die met de code door kunnen werken als wij klaar zijn.

Vormen van ondersteuning

We bieden ondersteuning in verschillende vormen. Vaak begint het met een modelscan. Zo’n modelscan kan gericht zijn op een bepaald issue dat de klant met zijn software heeft. Als dat over de rekentijd gaat, doen we meestal een korte studie naar de eigenschappen van de toepassing om te bepalen hoeveel versnelling er mogelijk is. Dat levert aanbevelingen die de ontwikkelaars van de klant zelf kunnen implementeren, al dan niet met onze hulp.

Vaak is een van onze aanbevelingen om het algoritme aan te passen. In sommige gevallen levert dit al voldoende versnelling op nog zonder dat er andere hardware wordt gebruikt. Zo’n verandering van algoritme is meestal niet heel eenvoudig. Vaak is het nodig om het algoritme goed passend te maken voor de toepassing. Onze experts hebben de kennis en ervaring om dit efficiënt en effectief te doen. Daarom vragen klanten ons Meestal om dat uit te voeren. Ook hierbij geldt weer dat we de ontwikkelaars van de klant meenemen in de aanpassing zodat ze er zelf mee door kunnen.

Als het veranderen van het algoritme niet voldoende is om de gewenste versnelling te bereiken, of niet uitvoerbaar, dan komt het aan op de expertise om de programmatuur optimaal gebruik te laten maken van de hardware. Tegenwoordig is dat vaak een GPGU. We zorgen ervoor dat de code configureerbaar is voor de specifieke eigenschappen van de GPGPU’s waarop het moet kunnen draaien en we houden de code toegankelijk voor ontwikkelaars die geen expert zijn op het gebied van GPGPU’s.

Neem gerust contact met ons op voor een verkennend gesprek. Zelfs als er geen opdracht uit komt vinden we het altijd leuk om onze kennis te delen.