C ++

GPU programavimas naudojant C ++

GPU programavimas naudojant C ++

Apžvalga

Šiame vadove mes išnagrinėsime GPU programavimo galingumą su C++. Kūrėjai gali tikėtis neįtikėtino našumo naudodami „C ++“, o pasiekę fenomenalią GPU galią žemo lygio kalba gali gauti greičiausią šiuo metu prieinamą skaičiavimą.

Reikalavimai

Nors bet kuri mašina, galinti paleisti modernią „Linux“ versiją, gali palaikyti kompiliatorių C ++, jums reikės NVIDIA pagrįsto GPU, kad galėtumėte sekti šį pratimą. Jei neturite GPU, galite sujungti GPU veikiantį egzempliorių „Amazon Web Services“ ar kitame pasirinktame debesų teikėjuje.

Jei pasirinksite fizinę mašiną, įsitikinkite, kad įdiegėte nuosavų „NVIDIA“ tvarkyklių. Nurodymus galite rasti čia: https: // linuxhint.com / install-nvidia-drivers-linux /

Be tvarkyklės, jums reikės CUDA įrankių rinkinio. Šiame pavyzdyje naudosime „Ubuntu 16“.04 LTS, tačiau daugeliui pagrindinių paskirstymų galima atsisiųsti šiuo URL: https: // kūrėjas.nvidia.com / cuda-downloads

Jei norite naudoti „Ubuntu“, pasirinkite .deb pagrįstas atsisiuntimas. Atsisiųstame faile nebus .deb plėtinys pagal numatytuosius nustatymus, todėl rekomenduoju jį pervadinti į .deb pabaigoje. Tada galite įdiegti naudodami:

sudo dpkg -i paketo pavadinimas.deb

Greičiausiai būsite paraginti įdiegti GPG raktą ir, jei taip, vykdykite pateiktas instrukcijas.

Tai atlikę atnaujinkite saugyklas:

sudo apt-get atnaujinimas
sudo apt-get install cuda -y

Kai tai bus padaryta, rekomenduoju iš naujo paleisti, kad viskas būtų tinkamai įkrauta.

GPU kūrimo nauda

Centriniai procesoriai valdo daugybę skirtingų įėjimų ir išėjimų ir juose yra didelis funkcijų asortimentas, skirtas ne tik patenkinti platų programos poreikių asortimentą, bet ir valdyti įvairias aparatūros konfigūracijas. Jie taip pat tvarko atmintį, talpyklą, sistemos magistralę, segmentavimą ir IO funkcijas, todėl jie yra visų sandorių lizdas.

GPU yra priešingai - juose yra daug atskirų procesorių, kurie orientuoti į labai paprastas matematines funkcijas. Dėl to jie užduotis apdoroja daug kartų greičiau nei procesoriai. Specializuodamiesi skaliarinėms funkcijoms (funkcijai reikalinga viena ar kelios įvestys, bet pateikiama tik viena išvestis), jos pasiekia ypatingą našumą kraštutinės specializacijos kaina.

Kodo pavyzdys

Kodo pavyzdyje mes įtraukiame vektorius kartu. Greičio palyginimui pridėjau kodo CPU ir GPU versiją.
gpu-pavyzdys.cpp žemiau pateiktas turinys:

#include "cuda_runtime.h "
# įtraukti
# įtraukti
# įtraukti
# įtraukti
# įtraukti
typedef std :: chrono :: high_resolution_clock Laikrodis;
#define ITER 65535
// Vektoriaus pridėjimo funkcijos procesoriaus versija
negaliojantis vector_add_cpu (int * a, int * b, int * c, int n)
int i;
// Pridėkite vektoriaus elementus a ir b prie vektoriaus c
už (i = 0; i < n; ++i)
c [i] = a [i] + b [i];


// GPU vektoriaus pridėjimo funkcijos versija
__global__ negaliojantis vector_add_gpu (int * gpu_a, int * gpu_b, int * gpu_c, int n)
int i = threadIdx.x;
// Ne reikia kilpai, nes CUDA vykdymo laikas
// siųs tai ITER kartus
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 * (int) dydis);
b = (int *) malloc (ITER * (int) dydis);
c = (int *) malloc (ITER * (int) dydis);
// Mums reikia kintamųjų, prieinamų GPU,
// taip cudaMallocManaged pateikia šiuos
cudaMallocManaged (& gpu_a, ITER * sizeof (int));
cudaMallocManaged (& gpu_b, ITER * sizeof (int));
cudaMallocManaged (& gpu_c, ITER * sizeof (int));
už (int i = 0; i < ITER; ++i)
a [i] = i;
b [i] = i;
c [i] = i;

// Iškvieskite centrinio procesoriaus funkciją ir nustatykite jos laiką
auto cpu_start = Laikrodis :: dabar ();
vector_add_cpu (a, b, c, ITER);
auto cpu_end = Laikrodis :: dabar ();
std :: cout << "vector_add_cpu: "
<< std::chrono::duration_cast(cpu_end - cpu_start).suskaičiuoti ()
<< " nanoseconds.\n";
// Iškvieskite GPU funkciją ir nustatykite jos laiką
// Trigubo kampo stabdžiai yra CUDA vykdymo laiko pratęsimas, leidžiantis
// turi būti perduoti CUDA branduolio skambučio parametrai.
// Šiame pavyzdyje mes perduodame vieną gijų bloką su ITER gijomis.
auto gpu_start = Laikrodis :: dabar ();
vector_add_gpu <<<1, ITER>>> (gpu_a, gpu_b, gpu_c, ITER);
cudaDeviceSynchronize ();
auto gpu_end = Laikrodis :: dabar ();
std :: cout << "vector_add_gpu: "
<< std::chrono::duration_cast(gpu_end - gpu_start).suskaičiuoti ()
<< " nanoseconds.\n";
// Atlaisvinkite GPU funkcija pagrįstą atminties paskirstymą
cudaFree (a);
cudaFree (b);
cudaFree (c);
// Atlaisvinkite atminties paskirstymą pagal procesoriaus funkciją
nemokamai (a);
laisvas (b);
laisvas (c);
grąžinti 0;

„Makefile“ žemiau pateiktas turinys:

INC = -I / usr / local / cuda / įtraukti
NVCC = / usr / local / cuda / bin / nvcc
NVCC_OPT = -std = c ++ 11
visi:
$ (NVCC) $ (NVCC_OPT) GPU pavyzdys.cpp -o gpu-pavyzdys
švarus:
-rm -f gpu-pavyzdys

Norėdami paleisti pavyzdį, sudarykite jį:

padaryti

Tada paleiskite programą:

./ gpu-pavyzdys

Kaip matote, procesoriaus versija (vector_add_cpu) veikia žymiai lėčiau nei GPU versija (vector_add_gpu).

Jei ne, gali tekti pakoreguoti ITER apibrėžimą „gpu-example“.cu į didesnį skaičių. Taip yra dėl to, kad GPU sąrankos laikas yra ilgesnis nei kai kurių mažesnių intensyvaus procesoriaus kilpų. Radau, kad mano mašinoje gerai veikia 65535, tačiau jūsų rida gali skirtis. Tačiau, kai jūs išvalysite šį slenkstį, GPU yra žymiai greitesnis nei procesorius.

Išvada

Tikiuosi, kad daug išmokote iš mūsų įvedimo į GPU programavimą su C++. Ankstesniu pavyzdžiu nepasiekiama daug, tačiau parodytos koncepcijos suteikia pagrindą, kurį galite naudoti įtraukdami savo idėjas, kad atskleistumėte savo GPU galią.

Pridėkite pelės gestus prie „Windows 10“ naudodami šiuos nemokamus įrankius
Pastaraisiais metais kompiuteriai ir operacinės sistemos labai išsivystė. Buvo laikas, kai vartotojai turėjo naudoti komandas naršydami per failų tvar...
Valdykite ir valdykite pelės judėjimą tarp kelių „Windows 10“ monitorių
„Dual Display Mouse Manager“ leidžia jums valdyti ir konfigūruoti pelės judėjimą tarp kelių monitorių, sulėtinant jo judėjimą šalia sienos. „Windows 1...
„WinMouse“ leidžia tinkinti ir pagerinti pelės žymeklio judėjimą „Windows“ kompiuteryje
Jei norite pagerinti numatytąsias pelės žymiklio funkcijas, naudokite nemokamą programinę įrangą „WinMouse“. Tai prideda daugiau funkcijų, kurios padė...