Programowanie kart graficznych

Podobne dokumenty
Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

Programowanie Współbieżne

Obliczenia na GPU w technologii CUDA

Programowanie procesorów graficznych NVIDIA (rdzenie CUDA) Wykład nr 1

Procesory kart graficznych i CUDA wer

Programowanie kart graficznych. Architektura i API część 1

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

Porównanie wydajności CUDA i OpenCL na przykładzie równoległego algorytmu wyznaczania wartości funkcji celu dla problemu gniazdowego

JCuda Czy Java i CUDA mogą się polubić? Konrad Szałkowski

Programowanie procesorów graficznych w CUDA.

Programowanie aplikacji równoległych i rozproszonych

Programowanie Równoległe wykład, CUDA, przykłady praktyczne 1. Maciej Matyka Instytut Fizyki Teoretycznej

Programowanie procesorów graficznych GPGPU. Krzysztof Banaś Obliczenia równoległe 1

CUDA. obliczenia na kartach graficznych. Łukasz Ligowski. 11 luty Łukasz Ligowski () CUDA 11 luty / 36

CUDA obliczenia ogólnego przeznaczenia na mocno zrównoleglonym sprzęcie. W prezentacji wykorzystano materiały firmy NVIDIA (

Procesory kart graficznych i CUDA wer PR

Programowanie Równoległe Wykład, CUDA praktycznie 1. Maciej Matyka Instytut Fizyki Teoretycznej

GTX260 i CUDA wer

Procesory kart graficznych i CUDA

Procesory kart graficznych i CUDA wer

Przetwarzanie Równoległe i Rozproszone

Programowanie kart graficznych

Programowanie CUDA informacje praktycznie i. Wersja

CUDA. cudniejsze przyk ady

Programowanie Równoległe wykład 12. OpenGL + algorytm n ciał. Maciej Matyka Instytut Fizyki Teoretycznej

Programowanie kart graficznych. Architektura i API część 2

CUDA ćwiczenia praktyczne

Programowanie procesorów graficznych GPGPU

Programowanie CUDA informacje praktycznie i przykłady. Wersja

ZARZĄDZANIE PAMIĘCIĄ W TECHNOLOGII CUDA

CUDA PROGRAMOWANIE PIERWSZE PROSTE PRZYKŁADY RÓWNOLEGŁE. Michał Bieńkowski Katarzyna Lewenda

Programowanie PKG - informacje praktycznie i przykłady. Wersja z Opracował: Rafał Walkowiak

Programowanie współbieżne i rozproszone

4 NVIDIA CUDA jako znakomita platforma do zrównoleglenia obliczeń

Jacek Matulewski - Fizyk zajmujący się na co dzień optyką kwantową i układami nieuporządkowanymi na Wydziale Fizyki, Astronomii i Informatyki

Dodatek A. CUDA. 1 Stosowany jest w tym kontekście skrót GPCPU (od ang. general-purpose computing on graphics processing units).

i3: internet - infrastruktury - innowacje

Programowanie procesorów graficznych GPGPU

CUDA część 1. platforma GPGPU w obliczeniach naukowych. Maciej Matyka

Programowanie z wykorzystaniem technologii CUDA i OpenCL Wykład 1

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Podstawy programowania komputerów

Tesla. Architektura Fermi

Programowanie kart graficznych. Kompilator NVCC Podstawy programowania na poziomie API sterownika

DYNAMICZNE PRZYDZIELANIE PAMIECI

Stałe, tablice dynamiczne i wielowymiarowe

Architektury komputerów Architektury i wydajność. Tomasz Dziubich

Struktura programu. Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem.

Programowanie równoległe Wprowadzenie do OpenCL. Rafał Skinderowicz

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

Globalne / Lokalne. Wykład 15. Podstawy programowania (język C) Zmienne globalne / lokalne (1) Zmienne globalne / lokalne (2)

Moc płynąca z kart graficznych

Hybrydowy system obliczeniowy z akceleratorami GPU

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

CUDA Median Filter filtr medianowy wykorzystujący bibliotekę CUDA sprawozdanie z projektu

Procesy i wątki. Krzysztof Banaś Obliczenia równoległe 1

Języki i metodyka programowania. Wskaźniki i tablice.

Wstęp do Programowania, laboratorium 02

Wskaźniki. Programowanie Proceduralne 1

Programowanie w modelu równoległości danych oraz dzielonej globalnej pamięci wspólnej. Krzysztof Banaś Obliczenia równoległe 1

Programowanie kart graficznych. Sprzęt i obliczenia

Implementacja modelu FHP w technologii NVIDIA CUDA

Programowanie równoległe i rozproszone. Praca zbiorowa pod redakcją Andrzeja Karbowskiego i Ewy Niewiadomskiej-Szynkiewicz

Wstęp do programowania

CUDA jako platforma GPGPU w obliczeniach naukowych

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 6. Karol Tarnowski A-1 p.

Akceleracja obliczeń algebry liniowej z wykorzystaniem masywnie równoległych, wielordzeniowych procesorów GPU Świerczewski Ł.

Przygotowanie kilku wersji kodu zgodnie z wymogami wersji zadania,

Język C zajęcia nr 11. Funkcje

Czyń CUDA (część 1) Powinieneś wiedzieć: Od czytelnika wymagana jest znajomość C++ oraz podstawowych zasad programowania równoległego.

Programowanie współbieżne Wprowadzenie do programowania GPU. Rafał Skinderowicz

Organizacja pamięci w procesorach graficznych

Wysokowydajna implementacja kodów nadmiarowych typu "erasure codes" z wykorzystaniem architektur wielordzeniowych

Programowanie procesorów graficznych GPGPU. Krzysztof Banaś Obliczenia równoległe 1

Wskaźniki w C. Anna Gogolińska

Zmienne, stałe i operatory

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

Język ludzki kod maszynowy

Wykład 4: Klasy i Metody

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Wskaźniki. Informatyka

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

wykład III uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - zarządzanie pamięcią, struktury,

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Temat zajęć: Tworzenie i obsługa wątków.

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

Lab 9 Podstawy Programowania

Politechnika Rzeszowska

Wstęp do programowania

Podstawy programowania w języku C++

Podstawy programowania C. dr. Krystyna Łapin

Funkcje. czyli jak programować proceduralne. Programowanie Proceduralne 1

Plan. krótkie opisy modułów. 1 Uwagi na temat wydajności CPython a. 2 Podstawowe techniki poprawiające wydajność obliczeniową

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Uzupełnienie dot. przekazywania argumentów

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Stałe i zmienne znakowe. Stała znakowa: znak

Metody Metody, parametry, zwracanie wartości

Procesory wielordzeniowe (multiprocessor on a chip) Krzysztof Banaś, Obliczenia wysokiej wydajności.

Transkrypt:

CUDA Compute Unified Device Architecture Programowanie kart graficznych mgr inż. Kamil Szostek AGH, WGGIOŚ, KGIS Wykorzystano materiały z kursu Programowanie kart graficznych prostsze niż myślisz M. Makowski i inni

Literatura NVIDIA CUDA Programming Guide NVIDIA CUDA Reference Manual NVIDIA CUDA Best Practices Guide CUDA w przykładach - J. Sanders, E. Kandrot 2

Po co? 3

Schemat architektur CPU vs GPU 4

Warstwy Aplikacji GPU 5

6

Architektury Compute Capability (Potencjał obliczeniowy) 1.0 Architektura Tesla GPUs 1.1 G92, G94, G96, G98, G84, G86 1.2 GT218, GT216, GT215 G80 1.3 GT200, GT200b 2.0 2.1 3.0 Fermi Kepler GF100, GF110 GF104, GF106 GF108, GF114, GF116, GF117, GF119 GK104, GK106, GK107 3.2 Tegra K1 3.5 GK110, GK208 3.7 GK210 5.0 Maxwell GM107, GM108 5.2 GM200, GM204, GM206 5.3 Tegra X1 7

CUDA C + CUDA Łatwy start dla programistów C/C++ Podstawy Kluczowe abstrakcje hierarchia wątków hierarcha pamięci model pamięci dzielonej na potrzeby współpracy wątków model synchronizacji 8

Hierarchia wątków wątki uruchamiane i wykonywane równolegle przy pomocy kernela - kodu uruchamianego na GPU (device) wszystkie wątki wykonują ten sam (szeregowy) program, ale mogą wchodzić w różne gałęzie każdy blok i każdy wątek posiadają unikalny identyfikator bloki mogą być jedno-, dwu- lub trojwymiarowe 9

Multiprocesor tworzy, zarządza, kolejkuje i uruchamia wątki w 32 elementowych grupach wątków równoległych zwanych warp. 10

Hierarchia pamięci rejestry (registers) p. lokalna (local) p. dzielona (shared) p. globalna (global) p. stałych (constant) 11

Kwalifikatory zmiennych Przykład deklaracji Typ pamięci Widoczność double v; rejestr (chyba, że przekroczono jego wielkość) wątek double array[10]; lokalna wątek shared double v; dzielona blok device double v; globalna aplikacja constant double v; globalna aplikacja 12

Wydajność pamięci przepustowość opóźnienia Typ pamięci Koszt (obrazowo) rejestry 1 dzielona 1 globalna 100-1000 lokalna 100-1000 pamięć stałych 1 13

Kwalifikatory funkcji global konieczny dla kernela musi mieć typ void uruchamiany z hosta (chyba, że CC >= 3.5) device wywoływane na GPU z innych funkcji host wywoływane przez hosta (domyślnie) można połączyć z device 14

Zmienne wewnątrz kernela Specjalne zmienne do identyfikacji wątków dim3 threadidx;// id wątku dim3 blockidx; // id bloku dim3 blockdim; // rozmiar bloku dim3 griddim; // rozmiar siatki = ilość bloków Synchronizacja wewnątrz bloku syncthreads(); 15

Podstawowy wzorzec uruchamiania obliczeń 16

Klasyczne podejście 17

Zarządzanie urządzeniami cudagetdevicecount( int* count ) cudasetdevice( int device ) cudagetdevice( int *current_device ) cudagetdeviceproperties( cudadeviceprop* prop, int device ) cudachoosedevice( int *device, cudadeviceprop* prop ) 18

Zarządzanie pamięcią Możliwe jest zarządzanie pamięcią GPU zarówno z poziomu hosta jak i urządzenia Alokowanie i zwalnianie pamięci Kopiowanie danych do i z globalnej pamięci urządzenia: cudamalloc(void **pointer, size_t nbytes) cudamemcpy(void *dst, void* src, size_t nbytes, dir); cudamemset(void *pointer, int value, size_t count) cudafree(void *pointer) 19

Przykład alokacji pamięci bez transferu danych int nbytes = 1024*sizeof(int); int *d_a = 0; cudamalloc( (void**)&d_a, nbytes ); cudamemset( d_a, 0, nbytes); //opcjonalnie... cudafree(d_a); 20

Przykład alokacji pamięci z transferem danych 1. // alokacja pamięci Hosta 2. int numbytes = N * sizeof(float) 3. float* h_a = (float*) malloc(numbytes); 4. //... Wypełnianie h_a... 5. // alokacja pamięci na urządzeniu 6. float* d_a = 0; 7. cudamalloc((void**)&d_a, numbytes); 8. // kopiowanie danych z pamięci hosta do urządzenia 9. cudamemcpy(d_a, h_a, numbytes, cudamemcpyhosttodevice); 10. // uruchomienie kernela... 11. gpu_func <<<exec-dims>>> (params) 12. // kopiowanie danych z pamięci urządzenia do hosta 13. cudamemcpy(h_a, d_a, numbytes, cudamemcpydevicetohost); 14. //zwalnianie pamięci urządzenia 15. cudafree(d_a); 16. //... Dalsze operacja na danych 21

Uruchamianie kernela nazwakernela <<<dim3 grid, dim3 block>>>( ) Przykłady: nazwakernela <<<500, 128>>>(...); // uruchamia 500 bloków, w każdym 128 wątków ---------------------------------- dim3 rozmiar_grida(128,32); dim3 rozmiar_blokow(16,16,2); nazwakernela <<< rozmiar_grida, rozmiar_grida >>>(...); // uruchamia 128*32=4096 bloków, w każdym 16*16*2=512 wątków 22

#include "stdio.h" Printf wewnątrz kernela dla CC >=2.0 global void hellocuda(float f) { printf("hello thread %d, f=%f\n", threadidx.x, f); } int main() { hellocuda<<<1, 5>>>(1.2345f); cudadevicesynchronize(); return 0; } //----------- na wyjściu: Hello thread 2, f=1.2345 Hello thread 1, f=1.2345 Hello thread 4, f=1.2345 Hello thread 0, f=1.2345 Hello thread 3, f=1.2345 23

BRAK SYNCHRONIZACJI BLOKÓW! 24

Pamięć Każdy wątek może: R / W rejestr wątku R / W pamięć lokalna wątku R / W pamięć dzielona bloku R / W pamięć globalna R / - pamięć stała (constant) R / - pamięć tekstur 25

26

27

// alokacja pamięci Hosta int numbytes = N * sizeof(float) float* h_a = (float*) malloc(numbytes); //... Wypełnianie h_a... // alokacja pamięci na urządzeniu float* d_a = 0; cudamalloc((void**)&d_a, numbytes); // kopiowanie danych z pamięci hosta do urządzenia cudamemcpy(d_a, h_a, numbytes, cudamemcpyhosttodevice); // uruchomienie kernela increment_gpu<<< N/blockSize, blocksize>>>(d_a, b); decrement_gpu<<< N/blockSize, blocksize>>>(d_a, b); // kopiowanie danych z pamięci urządzenia do hosta // SYNCHRONIZACJA! cudamemcpy(h_a, d_a, numbytes, cudamemcpydevicetohost); //zwalnianie pamięci urządzenia cudafree(d_a); //... Dalsze operacja na danych 28

Porównanie kodów CPU i GPU CPU GPU void increment_cpu(float *a, float b, int N) { for (int idx = 0; idx<n; idx++) a[idx] = a[idx] + b; } global void increment_gpu(float *a, float b, int N) { } int idx = blockidx.x * blockdim.x + threadidx.x; if (idx < N) a[idx] = a[idx] + b; void main() {... increment_cpu(a, b, N); } void main() {... dim3 dimblock (blocksize); dim3 dimgrid( ceil( N / (float)blocksize) ); increment_gpu<<<dimgrid, dimblock>>>(a, b, N);... } 29

Przykład optymalizacji odczytów pamięci global void increment_gpu(float *a, { } float *b, float *c, float *a_out, float *b_out, int N) int idx = blockidx.x * blockdim.x + threadidx.x; if (idx < N) { } a_out[idx] = a[idx] + b[idx] + c[idx]; b_out[idx] = a[idx] * b[idx] * c[idx]; global void increment_gpu(float *a, { } float *b, float *c, float *a_out, float *b_out, int N) int idx = blockidx.x * blockdim.x + threadidx.x; float a = a[idx]; float b = b[idx]; float c = c[idx]; if (idx < N) { } a_out[idx] = a + b + c; b_out[idx] = a * b * c; 30

Pamięć dzielona shared short cache[size]; extern shared int cache[]; Kernell<<<gridS, blocks, sharedsize>>>( ) syncthreads(); 31

Redukcja 32

Redukcja 33

34