C ++

GPU-programmering med C ++

GPU-programmering med C ++

Översikt

I den här guiden utforskar vi kraften i GPU-programmering med C++. Utvecklare kan förvänta sig otrolig prestanda med C ++, och åtkomst till den fenomenala kraften i GPU med ett lågnivåspråk kan ge några av de snabbaste beräkningarna som finns tillgängliga för närvarande.

Krav

Medan varje maskin som kan köra en modern version av Linux kan stödja en C ++ - kompilator, behöver du en NVIDIA-baserad GPU för att följa med den här övningen. Om du inte har en GPU kan du snurra upp en GPU-driven instans i Amazon Web Services eller en annan molnleverantör som du väljer.

Om du väljer en fysisk maskin, se till att du har NVIDIA-drivrutiner installerade. Du hittar instruktioner för detta här: https: // linuxhint.com / install-nvidia-drivers-linux /

Förutom föraren behöver du CUDA-verktygssatsen. I det här exemplet använder vi Ubuntu 16.04 LTS, men det finns nedladdningar tillgängliga för de flesta större distributioner på följande URL: https: // utvecklare.nvidia.com / cuda-nedladdningar

För Ubuntu skulle du välja .deb-baserad nedladdning. Den nedladdade filen har inte en .deb-förlängning som standard, så jag rekommenderar att du byter namn på den för att ha en .deb i slutet. Sedan kan du installera med:

sudo dpkg -i paketnamn.deb

Du kommer troligen att bli ombedd att installera en GPG-nyckel och i så fall följa instruktionerna för att göra det.

När du har gjort det uppdaterar du dina förråd:

sudo apt-get-uppdatering
sudo apt-get install cuda -y

När du är klar rekommenderar jag att du startar om för att säkerställa att allt är korrekt laddat.

Fördelarna med GPU-utveckling

Processorer hanterar många olika in- och utgångar och innehåller ett stort sortiment av funktioner för att inte bara hantera ett brett sortiment av programbehov utan också för att hantera olika hårdvarukonfigurationer. De hanterar också minne, cachning, systembuss, segmentering och IO-funktionalitet, vilket gör dem till en jack of all trades.

GPU: er är motsatsen - de innehåller många enskilda processorer som är fokuserade på mycket enkla matematiska funktioner. På grund av detta bearbetar de uppgifter många gånger snabbare än processorer. Genom att specialisera sig i skalära funktioner (en funktion som tar en eller flera ingångar men bara returnerar en enda utgång) uppnår de extrema prestanda på bekostnad av extrem specialisering.

Exempel på kod

I exempelkoden lägger vi till vektorer tillsammans. Jag har lagt till en CPU- och GPU-version av koden för hastighetsjämförelse.
gpu-exempel.cpp innehållet nedan:

#include "cuda_runtime.h "
#omfatta
#omfatta
#omfatta
#omfatta
#omfatta
typedef std :: chrono :: high_resolution_clock Clock;
#definiera ITER 65535
// CPU-version av vektortilläggsfunktionen
ogiltig vektor_add_cpu (int * a, int * b, int * c, int n)
int i;
// Lägg till vektorelementen a och b till vektorn c
för (i = 0; i < n; ++i)
c [i] = a [i] + b [i];


// GPU-version av vektortilläggsfunktionen
__global__ ogiltig vector_add_gpu (int * gpu_a, int * gpu_b, int * gpu_c, int n)
int i = threadIdx.x;
// Nej för loop krävs eftersom CUDA-körningen
// kommer att gänga detta ITER gånger
gpu_c [i] = gpu_a [i] + gpu_b [i];

int main ()
int * a, * b, * c;
int * gpu_a, * gpu_b, * gpu_c;
a = (int *) malloc (ITER * sizeof (int));
b = (int *) malloc (ITER * sizeof (int));
c = (int *) malloc (ITER * sizeof (int));
// Vi behöver variabler som är tillgängliga för GPU,
// så cudaMallocManaged tillhandahåller dessa
cudaMallocManaged (& gpu_a, ITER * sizeof (int));
cudaMallocManaged (& gpu_b, ITER * sizeof (int));
cudaMallocManaged (& gpu_c, ITER * sizeof (int));
för (int i = 0; i < ITER; ++i)
a [i] = i;
b [i] = i;
c [i] = i;

// Ring CPU-funktionen och tidsinställ den
auto cpu_start = Klocka :: nu ();
vector_add_cpu (a, b, c, ITER);
auto cpu_end = Klocka :: nu ();
std :: cout << "vector_add_cpu: "
<< std::chrono::duration_cast(cpu_end - cpu_start).räkna()
<< " nanoseconds.\n";
// Anropa GPU-funktionen och ta tid
// Trippelvinkelbromsarna är en CUDA runtime-förlängning som tillåter
// parametrar för ett CUDA-kärnanrop som ska skickas.
// I det här exemplet skickar vi ett trådblock med ITER-trådar.
auto gpu_start = Klocka :: nu ();
vector_add_gpu <<<1, ITER>>> (gpu_a, gpu_b, gpu_c, ITER);
cudaDeviceSynchronize ();
auto gpu_end = Klocka :: nu ();
std :: cout << "vector_add_gpu: "
<< std::chrono::duration_cast(gpu_end - gpu_start).räkna()
<< " nanoseconds.\n";
// Frigör GPU-funktionsbaserade minnestilldelningar
cudaFree (a);
cudaFree (b);
cudaFree (c);
// Frigör CPU-funktionsbaserade minnestilldelningar
gratis (a);
gratis (b);
gratis (c);
returnera 0;

Makefile innehållet nedan:

INC = -I / usr / local / cuda / include
NVCC = / usr / local / cuda / bin / nvcc
NVCC_OPT = -std = c ++ 11
Allt:
$ (NVCC) $ (NVCC_OPT) gpu-exempel.cpp -o gpu-exempel
rena:
-rm -f gpu-exempel

För att köra exemplet, kompilera det:

göra

Kör sedan programmet:

./ gpu-exempel

Som du kan se går CPU-versionen (vector_add_cpu) betydligt långsammare än GPU-versionen (vector_add_gpu).

Om inte, kan du behöva justera ITER-definitionen i gpu-exempel.cu till ett högre nummer. Detta beror på att GPU-installationstiden är längre än några mindre CPU-intensiva slingor. Jag hittade 65535 att fungera bra på min maskin, men din körsträcka kan variera. När du väl har tagit bort denna tröskel är GPU: n dramatiskt snabbare än CPU: n.

Slutsats

Jag hoppas att du har lärt dig mycket från vår introduktion till GPU-programmering med C++. Exemplet ovan uppnår inte mycket, men de visade koncepten ger ett ramverk som du kan använda för att integrera dina idéer för att släppa loss kraften i din GPU.

Så här installerar du League Of Legends på Ubuntu 14.04
Om du gillar League of Legends är det här en möjlighet för dig att testa League of Legends. Observera att LOL stöds på PlayOnLinux om du är en Linux-a...
Installera det senaste OpenRA-strategispelet på Ubuntu Linux
OpenRA är en Libre / Free Real Time Strategy-spelmotor som återskapar de tidiga Westwood-spelen som det klassiska Command & Conquer: Red Alert. Distri...
Installera senaste Dolphin Emulator för Gamecube & Wii på Linux
Dolphin Emulator låter dig spela dina valda Gamecube & Wii-spel på Linux Personal Computers (PC). Eftersom Dolphin Emulator är en fritt tillgänglig o...