C ++

Programování GPU v C ++

Programování GPU v C ++

Přehled

V této příručce prozkoumáme sílu programování GPU s C++. Vývojáři mohou očekávat neuvěřitelný výkon s C ++ a přístup k fenomenální síle GPU s nízkoúrovňovým jazykem může přinést jedny z nejrychlejších výpočtů, jaké jsou v současné době k dispozici.

Požadavky

Zatímco jakýkoli stroj schopný provozovat moderní verzi Linuxu může podporovat kompilátor C ++, budete potřebovat GPU založené na NVIDIA, které bude následovat spolu s tímto cvičením. Pokud nemáte GPU, můžete roztočit instanci poháněnou GPU v Amazon Web Services nebo u jiného poskytovatele cloudu podle vašeho výběru.

Pokud si vyberete fyzický stroj, ujistěte se, že máte nainstalované proprietární ovladače NVIDIA. Pokyny k tomu naleznete zde: https: // linuxhint.com / install-nvidia-drivers-linux /

Kromě ovladače budete potřebovat sadu nástrojů CUDA. V tomto příkladu použijeme Ubuntu 16.04 LTS, ale pro většinu hlavních distribucí jsou k dispozici soubory ke stažení na následující adrese URL: https: // vývojář.nvidia.com / cuda-stahování

U Ubuntu byste vybrali .deb založené stahování. Stažený soubor nebude mít .ve výchozím nastavení rozšíření deb, takže doporučuji jej přejmenovat, aby měl .deb na konci. Poté můžete nainstalovat pomocí:

sudo dpkg -i název-balíčku.deb

Pravděpodobně budete vyzváni k instalaci klíče GPG, a pokud ano, postupujte podle uvedených pokynů.

Jakmile to uděláte, aktualizujte své úložiště:

sudo apt-get aktualizace
sudo apt-get install cuda -y

Po dokončení doporučuji restartovat, aby bylo zajištěno, že je vše správně načteno.

Výhody vývoje GPU

CPU zpracovávají mnoho různých vstupů a výstupů a obsahují velký sortiment funkcí nejen pro řešení širokého sortimentu programových potřeb, ale také pro správu různých hardwarových konfigurací. Zpracovávají také paměť, ukládání do mezipaměti, systémovou sběrnici, segmentaci a funkce IO, což z nich dělá jacka všech obchodů.

GPU jsou opakem - obsahují mnoho jednotlivých procesorů, které jsou zaměřeny na velmi jednoduché matematické funkce. Z tohoto důvodu zpracovávají úkoly mnohokrát rychleji než CPU. Specializací na skalární funkce (funkce, která přijímá jeden nebo více vstupů, ale vrací pouze jeden výstup), dosáhnou extrémního výkonu za cenu extrémní specializace.

Příklad kódu

V ukázkovém kódu přidáme vektory dohromady. Přidal jsem CPU a GPU verzi kódu pro srovnání rychlosti.
GPU-příklad.cpp obsah níže:

#include „cuda_runtime.h "
#zahrnout
#zahrnout
#zahrnout
#zahrnout
#zahrnout
typedef std :: chrono :: high_resolution_clock Clock;
#define ITER 65535
// CPU verze funkce přidání vektoru
void vector_add_cpu (int * a, int * b, int * c, int n)
int i;
// Přidejte vektorové prvky aab do vektoru c
pro (i = 0; i < n; ++i)
c [i] = a [i] + b [i];


// GPU verze funkce přidání vektoru
__global__ void vector_add_gpu (int * gpu_a, int * gpu_b, int * gpu_c, int n)
int i = threadIdx.X;
// Není potřeba smyčka for, protože běhový modul CUDA
// bude vlákno ITER krát
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));
// Potřebujeme proměnné přístupné GPU,
// tak tyto poskytuje cudaMallocManaged
cudaMallocManaged (& gpu_a, ITER * sizeof (int));
cudaMallocManaged (& gpu_b, ITER * sizeof (int));
cudaMallocManaged (& gpu_c, ITER * sizeof (int));
pro (int i = 0; i < ITER; ++i)
a [i] = i;
b [i] = i;
c [i] = i;

// Vyvolá funkci CPU a načasuje ji
auto cpu_start = Hodiny :: nyní ();
vector_add_cpu (a, b, c, ITER);
auto cpu_end = Hodiny :: nyní ();
std :: cout << "vector_add_cpu: "
<< std::chrono::duration_cast(cpu_end - cpu_start).počet()
<< " nanoseconds.\n";
// Zavolejte funkci GPU a načasujte ji
// Brindle s trojitým úhlem je runtime rozšíření CUDA, které umožňuje
// parametry volání jádra CUDA, které mají být předány.
// V tomto příkladu předáváme jeden blok vláken s vlákny ITER.
auto gpu_start = Hodiny :: nyní ();
vector_add_gpu <<<1, ITER>>> (gpu_a, gpu_b, gpu_c, ITER);
cudaDeviceSynchronize ();
auto gpu_end = Hodiny :: nyní ();
std :: cout << "vector_add_gpu: "
<< std::chrono::duration_cast(gpu_end - gpu_start).počet()
<< " nanoseconds.\n";
// Uvolněte přidělení paměti založené na funkci GPU
cudaFree (a);
cudaFree (b);
cudaFree (c);
// Uvolněte přidělení paměti založené na funkci CPU
zdarma (a);
zdarma (b);
zdarma (c);
návrat 0;

Makefile obsah níže:

INC = -I / usr / local / cuda / include
NVCC = / usr / local / cuda / bin / nvcc
NVCC_OPT = -std = c ++ 11
Všechno:
$ (NVCC) $ (NVCC_OPT) příklad gpu.cpp -o příklad gpu
čistý:
-rm -f příklad gpu

Chcete-li spustit příklad, zkompilovat jej:

udělat

Poté spusťte program:

./ příklad gpu

Jak vidíte, verze CPU (vector_add_cpu) běží podstatně pomaleji než verze GPU (vector_add_gpu).

Pokud ne, možná budete muset upravit definici ITER v příkladu gpu.cu na vyšší číslo. To je způsobeno tím, že doba nastavení GPU je delší než u některých menších smyček náročných na CPU. Zjistil jsem, že 65535 na mém stroji funguje dobře, ale váš počet kilometrů se může lišit. Jakmile však tuto prahovou hodnotu zrušíte, GPU je dramaticky rychlejší než CPU.

Závěr

Doufám, že jste se z našeho úvodu do programování GPU pomocí C hodně naučili++. Výše uvedený příklad toho moc nedosahuje, ale předvedené koncepty poskytují rámec, který můžete použít k začlenění svých nápadů k uvolnění síly vašeho GPU.

Hry Nejlepší hry pro ruční sledování
Nejlepší hry pro ruční sledování
Oculus Quest nedávno představil skvělou myšlenku ručního sledování bez ovladačů. S neustále se zvyšujícím počtem her a aktivit, které provádějí podpor...
Hry Jak zobrazit překrytí OSD v linuxových aplikacích a hrách na celou obrazovku
Jak zobrazit překrytí OSD v linuxových aplikacích a hrách na celou obrazovku
Hraní her na celou obrazovku nebo používání aplikací v režimu celé obrazovky bez rozptýlení vás mohou odříznout od příslušných systémových informací v...
Hry Top 5 karet pro zachycení hry
Top 5 karet pro zachycení hry
Všichni jsme viděli a milovali streamování her na YouTube. PewDiePie, Jakesepticye a Markiplier jsou jen někteří z nejlepších hráčů, kteří vydělali mi...