Pokročilé architektury počítačů

Podobné dokumenty
Pokročilé architektury počítačů

Pokročilé architektury počítačů

Obecné výpočty na GPU v jazyce CUDA. Jiří Filipovič

GPU A CUDA HISTORIE GPU CO JE GPGPU? NVIDIA CUDA

CUDA J. Sloup a I. Šimeček

GPU a CUDA. Historie GPU. Co je GPGPU? Nvidia CUDA

GPGPU. Jan Faigl. Gerstnerova Laboratoř pro inteligentní rozhodování a řízení České vysoké učení technické v Praze

Úvod do GPGPU J. Sloup, I. Šimeček

Nvidia CUDA Paralelní programování na GPU

GPU a CUDA. Historie GPU. Co je GPGPU? Nvidia CUDA

OPS Paralelní systémy, seznam pojmů, klasifikace

PŘEDSTAVENÍ GRAFICKÉHO PROCESORU NVIDIA G200

Optimalizace pro GPU hardware

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY

Jan Nekvapil ČESKÉ VYSOKÉ UČENÍ TECHNICKÉ V PRAZE Fakulta elektrotechnická

Nvidia CUDA Paralelní programování na GPU

Řešíme úlohu zpracování velkého množství dat. Data jsou symetrická, úloha je dobře paralelizovatelná

Paralelní a distribuované výpočty (B4B36PDV)

Řešíme úlohu zpracování velkého množství dat. Data jsou symetrická, úloha je dobře paralelizovatelná. Propaganda výrobců grafických karet:

Základní operace. Prefix sum. Segmentovaný prefix-sum

IUJCE 07/08 Přednáška č. 6

vlastnosti, praktické zkušenosti

Správa paměti. doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 /

GPGPU Aplikace GPGPU. Obecné výpočty na grafických procesorech. Jan Vacata

Semestrální práce z předmětu Speciální číslicové systémy X31SCS

Základy informatiky. 2. Přednáška HW. Lenka Carr Motyčková. February 22, 2011 Základy informatiky 2

Přehled paralelních architektur. Dělení paralelních architektur Flynnova taxonomie Komunikační modely paralelních architektur

Pohled do nitra mikroprocesoru Josef Horálek

Přednášky o výpočetní technice. Hardware teoreticky. Adam Dominec 2010

Reprezentace dat v informačních systémech. Jaroslav Šmarda

Procesor Intel Pentium (1) Procesor Intel Pentium (3) Procesor Intel Pentium Pro (1) Procesor Intel Pentium (2)

Opakování programování

Co je grafický akcelerátor

Intel Itanium. Referát. Vysoká škola báňská Technická univerzita Ostrava Fakulta elektrotechniky a informatiky Katedra informatiky

PROCESOR. Typy procesorů

Sběrnicová struktura PC Procesory PC funkce, vlastnosti Interní počítačové paměti PC

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY

Jiné výpočetní platformy J. Sloup, M. Skrbek, I. Šimeček

Paralelní systémy. SIMD jeden tok instrukcí + více toků dat jedním programem je zpracováváno více různých souborů dat

Vyuºití GPGPU pro zpracování dat z magnetické rezonance

Přednáška 1. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Struktura programu v době běhu

Počítač jako elektronické, Číslicové zařízení

Hardware - komponenty počítačů Von Neumannova koncepce počítače. Von Neumannova koncepce počítače

Představení a vývoj architektur vektorových procesorů

Roman Výtisk, VYT027

Intel (2) Intel (1) Intel (3) Intel (4) Intel (6) Intel (5) Nezřetězené zpracování instrukcí:

Pokročilé architektury počítačů

Architektury paralelních počítačů I.

Procesy a vlákna (Processes and Threads)

Systém adresace paměti

Real Time programování v LabView. Ing. Martin Bušek, Ph.D.

GPU Computing.

2.8 Procesory. Střední průmyslová škola strojnická Vsetín. Ing. Martin Baričák. Název šablony Název DUMu. Předmět Druh učebního materiálu

Knihovny pro CUDA J. Sloup a I. Šimeček

Strojový kód k d a asembler procesoru MIPS SPIM. MIPS - prostředí NMS NMS. 32 ks 32bitových registrů ( adresa registru = 5 bitů).

09. Memory management. ZOS 2006, L.Pešička

C2115 Praktický úvod do superpočítání

Profilová část maturitní zkoušky 2017/2018

Gymnázium Vysoké Mýto nám. Vaňorného 163, Vysoké Mýto

REALIZACE SUPERPOČÍTAČE POMOCÍ GRAFICKÉ KARTY

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Představení a srovnání grafických procesorů ATI RV770 a NVIDIA G(T)200

Provádění instrukcí. procesorem. Základní model

Práce s binárními soubory. Základy programování 2 Tomáš Kühr

Procesor. Procesor FPU ALU. Řadič mikrokód

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY

SUPERPOČÍTAČE DANIEL LANGR ČVUT FIT / VZLÚ

Paralelní architektury se sdílenou pamětí typu NUMA. NUMA architektury

Zpráva o průběhu přijímacího řízení na vysokých školách dle Vyhlášky MŠMT č. 343/2002 a její změně 276/2004 Sb.

ZÁKLADY PROGRAMOVÁNÍ. Mgr. Vladislav BEDNÁŘ /14

Masivně paralelní zpracování obrazu v prostředí systému VisionLab Liberec Roman Cagaš, rc@mii.cz

Činnost CPU. IMTEE Přednáška č. 2. Několik úrovní abstrakce od obvodů CPU: Hodinový cyklus fáze strojový cyklus instrukční cyklus

Architektura Intel Atom

Paralelní programování

Metoda sledování paprsku na grafických akcelerátorech. Martin Zlatuška

Obsah. Kapitola 1 Hardware, procesory a vlákna Prohlídka útrob počítače...20 Motivace pro vícejádrové procesory...21

Matematika v programovacích

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

Operační systémy. Cvičení 4: Programování v C pod Unixem

PB002 Základy informačních technologií

Implementace numerických metod v jazyce C a Python

Profilová část maturitní zkoušky 2014/2015

Vláknové programování část I

Ústav technické matematiky FS ( Ústav technické matematiky FS ) / 35

Řízení IO přenosů DMA řadičem

8 Třídy, objekty, metody, předávání argumentů metod

Cell broadband engine architecture

Bitové operátory a bitová pole. Úvod do programování 2 Tomáš Kühr

Úvod SISD. Sekvenční výpočty SIMD MIMD

VYUŽITÍ GRAFICKÉHO ADAPTÉRU PRO OBECNÉ VÝPOČTY GENERAL-PURPOSE COMPUTATION USING GRAPHICS CARD

Práce s pamětí a předávání parametrů. Úvod do programování 1

Sběrnicová struktura PC Procesory PC funkce, vlastnosti Interní počítačové paměti PC

Správa paměti. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta, 2016

Více o konstruktorech a destruktorech

2 Hardware a operační systémy

Architektury VLIW M. Skrbek a I. Šimeček

Xbox 360 Cpu = IBM Xenon

Funkce, intuitivní chápání složitosti

INDIVIDUÁLNÍ PROJEKT 1 - ZPRACOVÁNÍ GNSS SIGNÁLU V GPU

Transkript:

Pokročilé architektury počítačů Tutoriál 3 CUDA - GPU Martin Milata

Výpočetní model CUDA Organizace kódu Sériově organizovaný kód určený pro CPU Paralelní kód prováděný na GPU Označuje se jako kernel GPU kernel provádí se na tzv. grid struktuře Grid se skládá z bloků (1D nebo 2D struktura) Blok je skupina až 512 vláken organizovaných do 1, 2 nebo 3 rozměrného pole Hierarchizované uspořádání paralelismů

Paměťový model CUDA Definuje různé adresní prostory pro přístup v rámci GPU a komunikaci s CPU Globální paměť, paměť konstant a textur jsou přístupné GPU a CPU Registry, lokální a sdílená paměť přístupné GPU Latence paměti Rychlá paměť s nízkou latencí registry a sdílená paměť Frame buffer (DRAM paměť) lokální paměť, paměť konstant a textur

GT200 Více-jádrový čip s dvou vrstvou hierarchií 10x Thread Processing Cluster (TPC) na vyšší úrovni 3x Streaming Multiprocessor (SM) nebo Thread Processor Array (TPA) na nižší úrovni v rámci každého TPC Hierarchie definovaná realizací přístupu do paměti SM v rámci TPC sdílí přístup k hierarchií cache pamětí v rámci přístupu do paměti textur

Bližší pohled na výpočetní architekturu GT200 Streaming Multiprocessor (SM) SM Controller Instrukční cache Warp buffer Tabulka skóre 8x Streaming Processor (SP) Funkční jednotka 2x speciální funkční jednotka souvisí s grafickými výpočty lze je použít jako násobičky 1x 64bit funkční jednotka 16k 32bit registrů 16kB sdílené paměti

Třetí generace SM 32x CUDA Core provádí celočíselné operace i operace v plovoucí řádové čárce ALU a FPU single i double precision 64KB Sdílené paměti Konfiguračně rozdělena mezi L1 cache a sdílenou paměť (16KB x 48KB pro sdílenou paměť nebo cache) 16x L/S jednotka Jednotná cesta přístupu do paměti (dříve separována paměť textur čtení a výstupní pixel zápis) 4x SFU Speciální operace sin, cos, exp, rcp Obrázek převzat z: Whitepaper NVIDIA's Next Generation CUDA Compute Architecture: Fermi

Třetí generace SM plánování instrukcí Obrázek převzat z: nvidia.com

Máte CUDA enabled zařízení? Převzato z: http://www.nvidia.com/object/cuda_gpus.html Seznam není aktuální (verze z roku 2009)

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Stanovení velikosti vektoru Počet prvků vektoru (10) Nastavení počtu vláken bloku Maximální počet vláken v bloku (4) Důsledek je popis velikosti gridu int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, sizeof(float)*n, cudamemcpydevicetohost); Počet prvků / Počet vláken bloku printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Definice CUDA kernelu Realizuje paralelní výpočet druhých mocnin prvků vektoru na GPU float *a ukazatel do paměti GPU zařízení int N skutečný počet prvků int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, sizeof(float)*n, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Definice CUDA kernelu Realizuje paralelní výpočet druhých mocnin prvků vektoru na GPU float *a ukazatel do paměti GPU zařízení int N skutečný počet prvků int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, sizeof(float)*n, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Alokace a inicializace vektoru v hlavní paměti ( paměť CPU ) Vektor a_h velikosti N float hodnot je k dispozici v paměti CPU size jako celková velikost pole pro uložení N float hodnot bude použita i při následné alokaci GPU paměti int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, sizeof(float)*n, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Alokace a kopírování hodnot vektoru do paměti GPU Vektor a_d velikosti N float hodnot je alokován v paměti GPU Při kopírování pamětí je specifikován a_d cíl a a_h zdroj přenosu, size velikost kopírované oblasti a cudamemcpyhosttodevice směr přenosu int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, sizeof(float)*n, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Výpočet počtu bloků vláken, do kterých bude provádění rozprostřeno Proměnná n_blocks definuje počet bloků v rámci gridu v 1D uspořádání Případný nenulový zbytek celočíselného podílu počtu prvků a počtu vláken v bloku vynutí alokaci bloku navíc (nebude plně využit) int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, sizeof(float)*n, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Volání provádění CUDA kernelu Za voláním funkce kernelu následují parametry direktivy volání n_blocks počet bloků a block_size jejich velikost (počet vláken v bloku) Vektor a_d je předán jako ukazatel do paměti GPU, následuje konstantní N int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, sizeof(float)*n, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Kopírování hodnoty vypočtem modifikovaného vektoru zpět do paměťového prostoru CPU Při kopírování pamětí je opět specifikován a_h cíl a a_d zdroj přenosu, size velikost kopírované oblasti a cudamemcpydevicetohost směr přenosu int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, size, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Zobrazení výsledku int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, size, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Příklad: Druhá mocnina prvků vektoru const int N = 10; const int blocksize = 4; global void square_array(float *a,int N) { int idx=blockidx.x*blockdim.x+threadidx.x; if (idx<n) a[idx] = a[idx] * a[idx]; Úklid dynamicky alokovaných pamětí před ukončením provádění programu Uvolnění alokované paměti v prostoru GPU pomocí cudafree(a_d) Uvolnění paměti v prostoru CPU pomocí free(a_h) int main(void) { float *a_h; const size_t size = N*sizeof(float); a_h = (float *)malloc(size); a_h[i] = (float)i; float *a_d; cudamalloc((void **) &a_d, size); cudamemcpy(a_d, a_h, size, cudamemcpyhosttodevice); int n_blocks = N/block_size + (N%block_size == 0? 0:1); square_array <<<n_blocks, block_size>>>(a_d,n); cudamemcpy(a_h, a_d, size, cudamemcpydevicetohost); printf("%d %f\n", i, a_h[i]); cudafree(a_d); free(a_h);

Vykonávání vláken Struktura GPU Obsahuje N multiprocesorů Každý multiprocesor obsahuje M skalárních procesorů Každý multiprocesor zpracovává skupiny bloků vláken Blok vláken může běžet jen na jednom multiprocesoru Bloky jsou rozděleny do skupin vláken tzv. warp Warp je prováděn paralelně V současné době obsahuje 32 vláken Vlákna jsou ve warp řazena pokud možno se sekvenčně vzrůstajícím threadid Plánovač přepíná provádění mezi warp instrukcemi

CUDA výpočetní server Server Host: Uživatel: Heslo: Přihlášení tesla.cs.vsb.cz pap_cuda cuda_test ssh -X pap_cuda@tesla.cs.vsb.cz Kopírování zdrojového kódu na serveru mkdir./<login> cp./src/*./<login>/ Kompilace CPU gcc -lrt <soubor>.c GPU nvcc <soubor>.cu

CUDA práce s kódem Editace kódu Úkol gedit ~/<login>/<soubor> & Získejte doby provádění kódu pro vyplnění následující tabulky Inicializace (příprava matic) kopírování dat (přesun mezi pamětmi CPU a GPU) výpočet kopírování dat (přesun mezi pamětmi GPU a CPU CPU GPU

Literatura D. Kanter: NVIDIA's GT200: Inside a Papallel Processor NVIDIA CUDA C Programming Guide Johan Seland: CUDA Programming Paul H. J. Kelly, Advanced Computer Architecture Lecture notes 332 P. N. Glaskowsky: NVIDIA s Fermi: The First Complete GPU Computing Architecture Internetové zdroje: http://www.nvidia.com/ http://gpgpu.org/