Programowanie procesorów graficznych GPGPU

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

Programowanie procesorów graficznych GPGPU

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

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

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

i3: internet - infrastruktury - innowacje

Programowanie Współbieżne

Programowanie kart graficznych

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

Przetwarzanie Równoległe i Rozproszone

Tworzenie programów równoległych cd. Krzysztof Banaś Obliczenia równoległe 1

Tesla. Architektura Fermi

Programowanie CUDA informacje praktycznie i. Wersja

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

Wydajność programów sekwencyjnych. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1

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

Moc płynąca z kart graficznych

Programowanie aplikacji równoległych i rozproszonych

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

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

Programowanie CUDA informacje praktycznie i przykłady. Wersja

Wydajność systemów a organizacja pamięci. Krzysztof Banaś, Obliczenia wysokiej wydajności. 1

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

PROGRAMOWANIE WSPÓŁCZESNYCH ARCHITEKTUR KOMPUTEROWYCH DR INŻ. KRZYSZTOF ROJEK

Wydajność systemów a organizacja pamięci. Krzysztof Banaś, Obliczenia wysokiej wydajności. 1

Wydajność systemów a organizacja pamięci. Krzysztof Banaś, Obliczenia wysokiej wydajności. 1

Programowanie z wykorzystaniem technologii CUDA i OpenCL Wykład 1

Wydajność systemów a organizacja pamięci, czyli dlaczego jednak nie jest aż tak źle. Krzysztof Banaś, Obliczenia wysokiej wydajności.

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

Nowoczesne technologie przetwarzania informacji

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

Przygotowanie kilku wersji kodu zgodnie z wymogami wersji zadania,

Programowanie kart graficznych

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

Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1

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

Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1

Numeryczna algebra liniowa

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

PROGRAMOWANIE WSPÓŁCZESNYCH ARCHITEKTUR KOMPUTEROWYCH DR INŻ. KRZYSZTOF ROJEK

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

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

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

Architektura komputerów

Implementacja sieci neuronowych na karcie graficznej. Waldemar Pawlaszek

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

Alternatywne modele programowania równoległego

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

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

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

Wstęp do obliczeń równoległych na GPU

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

Libra.cs.put.poznan.pl/mailman/listinfo/skisrkolo.

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

Larrabee GPGPU. Zastosowanie, wydajność i porównanie z innymi układami

Literatura. 11/16/2016 Przetwarzanie równoległe - wstęp 1

CUDA ćwiczenia praktyczne

Zadania na zaliczenie przedmiotu Przetwarzanie równoległe Zebrał dla roku.ak. 2015/2016 Rafał Walkowiak,

Organizacja pamięci w procesorach graficznych

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

Budowa komputera. Magistrala. Procesor Pamięć Układy I/O

Programowanie procesorów graficznych w CUDA.

Programowanie kart graficznych. Sprzęt i obliczenia

Algorytmy dla maszyny PRAM

Obliczenia Wysokiej Wydajności

Skalowalność obliczeń równoległych. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1

10/14/2013 Przetwarzanie równoległe - wstęp 1. Zakres przedmiotu

Literatura. 3/26/2018 Przetwarzanie równoległe - wstęp 1

Wykorzystanie architektury Intel MIC w obliczeniach typu stencil

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

Zrównoleglenie i przetwarzanie potokowe

Tworzenie programów równoległych. Krzysztof Banaś Obliczenia równoległe 1

Sprzęt komputerowy 2. Autor prezentacji: 1 prof. dr hab. Maria Hilczer

Sprzęt komputerowy 2. Autor prezentacji: 1 prof. dr hab. Maria Hilczer

Architektura mikroprocesorów TEO 2009/2010

Raport Hurtownie Danych

Julia 4D - raytracing

Metody optymalizacji soft-procesorów NIOS

PROBLEMATYKA OBLICZEŃ MASOWYCH W NAUKACH O ZIEMI. Satelitarny monitoring środowiska

Zapoznanie z technikami i narzędziami programistycznymi służącymi do tworzenia programów współbieżnych i obsługi współbieżności przez system.

Wstęp. Przetwarzanie równoległe. Krzysztof Banaś Obliczenia równoległe 1

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

Architektura komputerów

Operacje grupowego przesyłania komunikatów

XIII International PhD Workshop OWD 2011, October 2011 REALIZACJA OBLICZEŃ W ARCHITEKTURZE MASOWO RÓWNOLEGŁEJ W HETEROGENICZNYCH SYSTEMACH

Projektowanie algorytmów równoległych. Zbigniew Koza Wrocław 2012

Programowanie równoległe Wprowadzenie do programowania GPU. Rafał Skinderowicz

Budowa i użytkowanie klastrów w opaciu o układy Cell BE oraz GPU

Praca dyplomowa magisterska

Operacje grupowego przesyłania komunikatów. Krzysztof Banaś Obliczenia równoległe 1

ROZPROSZONY SYSTEM DO KRYPTOANALIZY SZYFRÓW OPARTYCH NA KRZYWYCH ELIPTYCZNYCH

Optymalizacja skalarna. Piotr Bała. Wykład wygłoszony w ICM w czercu 2000

16. Taksonomia Flynn'a.

Budowa komputera Komputer computer computare

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

Systemy wbudowane. Uproszczone metody kosyntezy. Wykład 11: Metody kosyntezy systemów wbudowanych

Dr inż. hab. Siergiej Fialko, IF-PK,

Budowa komputera. Magistrala. Procesor Pamięć Układy I/O

Wprowadzenie do GPGPU

Numeryczna algebra liniowa. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1

Transkrypt:

Programowanie procesorów graficznych GPGPU 1

OpenCL projektowanie kerneli Przypomnienie: kernel program realizowany przez urządzenie OpenCL wątek (work item) rdzeń (processing element): jeden wątek wykonywany jest przez jeden rdzeń grupa wątków (work group) jednostka obliczeniowa (compute unit): grupa wątków wykonuje obliczenia na jednej jednostce obliczeniowej grupa wątków powinna mieć więcej wątków niż rdzeni w jednostce obliczeniowej grupa dzielona jest na podgrupy, wavefronts/warps, wątków wykonywanych jednocześnie w modelu SIMD przestrzeń wątków urządzenie: wszystkie watki z przestrzeni realizują zlecony kernel na urządzeniu 2

3

OpenCL organizacja wątków 4

Przestrzeń wątków 5

OpenCL projektowanie kerneli Przypomnienie: wielopoziomowa hierarchia pamięci: rejestry najszybsze zmienne lokalne (jeśli nie jest ich za dużo, register spilling) prywatne dla każdego wątku pamięć wspólna szybka zmienne (tablice) z atrybutem local wspólne dla wątków z jednej grupy roboczej pamięć globalna powolna zmienne lokalne nie mieszczące się w rejestrach zmienne (tablice) z atrybutem local» wspólne dla wszystkich wątków dodatkowe rodzaje pamięci: constant, texture 6

OpenCL model pamięci 7

8

9

OpenCL ukrywanie opóźnienia Ukrywanie opóźnienia (latency hiding) w dostępie do pamięci dla CPU i GPU Konieczne jest współbieżne wykonywanie co najmniej kilku (najlepiej kilkunastu) grup wątków (AMD wavefronts, NVIDIA warps) Podział na grupy wątków dokonujących jednoczesnego dostępu do pamięci jest ukryty przed programistą 10

OpenCL zależności danych 11

Projektowanie kerneli Model równoległości danych (data parallel programming) model zrównoleglenia: dekompozycja danych (data decomposition) każdy wątek realizuje ten sam kod (SPMD) synchronizacja sprzętowa (SIMD, SIMT) OpenCL pozwala uzyskać informacje o liczbie wymiarów przestrzeni wątków, liczbie wątków (globalnej oraz w pojedynczej grupie), liczbie grup oraz o identyfikatorze wątku: lokalnym (w grupie), globalnym, a także o identyfikatorze grupy: get_work_dim() get_global_id(dim_id), get_local_id(dim_id) get_global_size(dim_id), get_local_size(dim_id) get_num_groups(dim_id), get_group_id(dim_id) 12

Projektowanie kerneli Model SPMD wprowadzany klasycznie poprzez identyfikatory wątków wątek na podstawie swojego identyfikatora może: zlokalizować dane, na których dokonuje przetwarzania dane[ f(my_id) ] wybrać ścieżkę wykonania programu if(my_id ==...){...} określić iteracje pętli, które ma wykonać for( i=f1(my_id); i< f2(my_id); i += f3(my_id) ){... } w tym aspekcie programowanie GPU jest zbliżone do modeli Pthreads i MPI Środowiska programowania GPU pozwalają na wykorzystanie liczb wątków rzędu milionów 13

OpenCL model pamięci Spójność pamięci: dla wątków tej samej grupy spójny obraz pamięci jest uzyskiwany w punktach synchronizacji np. wywołanie barrier (CLK_GLOBAL_MEM_FENCE); barrier (CLK_LOCAL_MEM_FENCE); dla wszystkich wątków wykonujących kernel spójny obraz pamięci jest uzyskiwany po wykonaniu kernela Szybkość pamięci: global local: ponad 100GB/s zależna od wzorca dostępu (coalesced memory access) host global: 6GB/s (PCIe 2.0) 14

Przykład Przykład dodawania wektorów (OpenCL) dekompozycja zadania analiza wydajności wydajność przetwarzania wydajność dostępu do pamięci czynniki wpływające na wydajność:» liczba wątków» liczba współbieżnych żądań dostępu do pamięci dla pojedynczego wątku» rozmiar danych w pojedynczym żądaniu 15

Projektowanie kerneli przykład Przykład programu dodawania wektorów dekompozycja danych wariant 1 jeden wątek na jeden element wektora wykorzystanie możliwości tworzenia milionów wątków zawstydzająco równoległy algorytm brak komunikacji, synchronizacji kernel void vecadd_1_kernel( global const float *a, global const float *b, global float *result) { int gid = get_global_id(0); result[gid] = a[gid] + b[gid]; } 16

Projektowanie kerneli przykład Prosty przykład programu dodawania wektorów dekompozycja danych wariant 2 wykorzystanie wariantów podziału danych blokowanie jeden wątek operuje na bloku danych kernel void vecadd_2_blocks_kernel(..., const int size, const int size_per_thread) { int gid = get_global_id(0); int index_start = gid * size_per_thread; int index_end = (gid+1) * size_per_thread; for (int i=index_start; i < index_end && i < size; i++) { result[i] = a[i]+b[i]; }} 17

Projektowanie kerneli przykład Prosty przykład programu dodawania wektorów dekompozycja danych wariant 3 wykorzystanie wariantów podziału danych podział cykliczny kolejne wątki z grupy operują na kolejnych elementach wektorów strategia niewłaściwa dla CPU, najlepsza dla GPU kernel void vecadd_3_cyclic_kernel(..., const int size) { int index_start = get_global_id(0); int index_end = size; int stride = get_local_size(0) * get_num_groups(0); for (int i=index_start; i < index_end; i+=stride) { result[i] = a[i]+b[i]; }} 18

Projektowanie kerneli przykład Prosty przykład programu dodawania wektorów dekompozycja danych wariant 3 wykorzystanie wariantów podziału danych podział cykliczny wykorzystanie typów wektorowych żądanie dostępu do pamięci dla pojedynczego wątku dotyczy 128 bitów, zamiast 32 kernel void vecadd_4_cyclic_vect_kernel( global const float4 *a, global const float4 *b, global float4 *result, const int size) { int index_start = 4 * get_global_id(0); int index_end = size/4; int stride = 4 * get_local_size(0) * get_num_groups(0); for (int i=index_start; i < index_end; i+=stride) { result[i] = a[i]+b[i]; }} 19

Analiza wydajności Analiza wydajności może być przeprowadzana na dwa standardowe sposoby: wydajność względna klasycznie oznacza to przyspieszenie i efektywność jako funkcje liczby procesorów/rdzeni dla pojedynczego GPU trudno przeprowadzać takie analizy analizy porównujące wydajność CPU i GPU stwarzają wiele problemów metodologicznych i powinny być używane tylko jako pewne wskazówki wydajność bezwzględna procent teoretycznej maksymalnej wydajności uzyskany dla danego wykonania programu wydajność może być ograniczana przez wydajność przetwarzania lub wydajność transferu danych z/do pamięci (dla obliczeń na GPU powinno się uwzględnić szybkości transferu dla wszystkich poziomów pamięci) 20

Analiza wydajności W przypadku prostego kernela dodawania wektorów wydajność jest w całości ograniczana przez szybkość dostępu do pamięci W celu maksymalizacji szybkości zapisu/odczytu należy wygenerować maksymalna liczbę żądań dostępu do pamięci: należy zwiększać liczbę aktywnych wątków ale istnieją ograniczenia na liczbę aktywnych wątków i grup wątków można zwiększać liczbę niezależnych dostępów do danych przez pojedynczy wątek np. poprzez wykorzystanie pobierania float4 (128 bitów) zamiast zamiast zwykłego float (32 bity) lub przez modyfikację kodu źródłowego, np. rozwijanie pętli (należy upewnić się, że dostępy są traktowane jako niezależne) 21

Przykład paramerów GPU Przykład karty graficznej (laptop Dell Vostro 3450): AMD Radeon HD 6630M 6 CU 480 PE 16384 rejestrów wektorowych (128 bitowych) / CU 32 kb pamięci wspólnej (32 banki) / CU 8 kb L1 / CU, 256 kb L2 / GPU 480 Gflops 25,6 GB/s DDR3, 51,2 GDDR5 ok. 250 GB/s pamięć wspólna maksymalny rozmiar grupy 256 (cztery wavefronts ) maksymalna liczba wavefronts 248 / GPU 22

Przykład paramerów GPU NVIDIA Tesla M2075 (architektura Fermi) 14 CU 448 PE ( 32PE / CU ) 32768 rejestrów 32 bitowych / CU 48 kb pamięci wspólnej / CU 73.6 GB/s / CU 16 kb L1 / CU, 224 kb L2 / GPU 515 DP GFLOPS 150 GB/s GDDR5 maksymalny rozmiar grupy 1024 (32 warps ) maksymalna liczba aktywnych grup / CU 8 maksymalna liczba aktywnych warps / CU 48 maksymalna liczba rejestrów na wątek 63 maksymalna liczba aktywnych wątków 1536 23

Przykład paramerów GPU NVIDIA Tesla K20 (architektura Kepler) 13 CU 2496 PE ( 192PE / CU ) 65536 rejestrów 32 bitowych / CU 48 kb pamięci wspólnej / CU 16 kb L1 / CU, 208 kb L2 / GPU 1170 DP GFLOPS 5GB GDDR5 RAM przepustowość 208 GB/s maksymalny rozmiar grupy 1024 (32 warps ) maksymalna liczba aktywnych grup / CU 16 maksymalna liczba aktywnych warps / CU 64 maksymalna liczba rejestrów na wątek 255 maksymalna liczba aktywnych wątków 2048 24

Przykład paramerów GPU AMD (ATI) Radeon HD 5870 20 CU 320x5 PE ( 16x5PE / CU ) każdy rdzeń posiada 5 ALU 544 DP GFLOPS 16384 rejestrów 4x32 bitowych / CU 13056 GB/s 32 kb pamięci wspólnej / CU 100 GB/s / CU, 2176 GB/s 8 kb L1 / CU przepustowość 1088 GB/s 512 kb L2 / GPU przepustowość L1 L2: 435 GB/s 1 GB GDDR5 RAM przepustowość 154 GB/s maksymalny rozmiar grupy 1024 (32 warps ) maksymalna liczba aktywnych grup / CU 8 maksymalna liczba aktywnych wavefronts / CU 24.8 maksymalna liczba rejestrów na wątek 63 maksymalna liczba aktywnych wątków 1536 25

Wyniki AMD Radeon HD 5870 PARAMETERS: nr_cu 20, nr_cores 6400, nr_cores_per_cu 320 workgroup size 256, nr_workgroups 240,nr_workgroups_per_CU 12 nr_threads 61440, nr_threads_per_cu 3072, nr_threads_per_core 3840 array size 31457280, nr_entries_per_thread 512, nr_entries_per_core 1966080 4. executing kernel 1, on platform 0 and device 0 EXECUTION TIME: executing kernel: 0.079807 (profiler: 0.079346) Number of operations 31457280, performance 0.396455 GFlops GBytes transferred to processor 0.377487, speed 4.757464 GB/s 4. executing kernel 2, on platform 0 and device 0 EXECUTION TIME: executing kernel: 0.003577 (profiler: 0.003200) Number of operations 31457280, performance 9.829715 GFlops GBytes transferred to processor 0.377487, speed 117.956580 GB/s 4. executing kernel 3, on platform 0 and device 0 (GPU) EXECUTION TIME: executing kernel: 0.003008 (profiler: 0.002649) Number of operations 31457280, performance 11.873163 GFlops GBytes transferred to processor 0.377487, speed 142.477954 GB/s 26

GPGPU 27

Przykład transpozycja macierzy 28

Przykład transpozycja macierzy 29

Przykład transpozycja macierzy Wykorzystanie: pamięci wspólnej: jako szybkiej pamięci podręcznej umożliwiającej komunikację pomiędzy watkami jawnej synchronizacji pracy wątków 30

CUDA kernel global void transpose( float *out, float *in, int w, int h ) { shared float block[block_dim*block_dim]; unsigned int xblock = blockdim.x * blockidx.x; unsigned int yblock = blockdim.y * blockidx.y; unsigned int xindex = xblock + threadidx.x; unsigned int yindex = yblock + threadidx.y; unsigned int index_out, index_transpose; if ( xindex < width && yindex < height ) { unsigned int index_in = width * yindex + xindex; unsigned int index_block = threadidx.y * BLOCK_DIM + threadidx.x; block[index_block] = in[index_in]; index_transpose = threadidx.x * BLOCK_DIM + threadidx.y; index_out = height * (xblock + threadidx.y) + yblock + threadidx.x; } synchthreads(); if(xindex<width&&yindex<height) out[index_out]=block[index_transpose]; } 31

Przykład mnożenie macierzy Przypomnienie: mnożenie macierzy jest algorytmem, dla którego przy nieskończonej liczbie rejestrów występuje bardzo korzystny stosunek liczby operacji do liczby dostępów do pamięci 3 2 s = (2n )/(3n ) ~ 2n/3 pm (n rozmiar macierzy) przy małej liczbie rejestrów i małym rozmiarze pamięci podręcznej naiwna implementacja prowadzi do znacznego spadku stosunku spm: 3 3 spm = (2n )/(n +...) ~ 2 implementacja naiwna schemat przechowywania wierszami: c(row, col) = c[row*n + col] for(i=0;i<n;i++){ for(j=0;j<n;j++){ c[i*n+j]=0.0; for(k=0;k<n;k++){ c[i*n+j] += a[i*n+k]*b[k*n+j]; } } } 32

Przykład mnożenie macierzy Naiwna implementacja GPU jeden wątek na jeden element macierzy wynikowej C Operacje wyłącznie na pamięci globalnej Nieoptymalny dostęp do tablicy A kernel void mat_mul_1_kernel( global float* A, global float* B, global float* C, int N ) { int i; int row = get_global_id(1); int col = get_global_id(0); float temp = 0.0; for (i = 0; i < N; i++) { temp += A[row * N + i] * B[i * N + col]; } C[row * N + col] = temp; } 33

Przykład mnożenie macierzy Klasyczna technika optymalizacji blokowanie Wyróżnienie bloków w tablicach A, B i C przechowywanych w szybkiej pamięci Wykonanie jak największej liczby operacji na blokach w szybkiej pamięci 34

Przykład mnożenie macierzy Implementacja blokowania: wariant 1 duże bloki: rozmiar bloku dobrany tak, żeby blok mieścił się w szybkiej pamięci (cache blocking) pojedynczy wątek wykonuje obliczenia dla wielu wyrazów bloku wariant 2 małe bloki: rozmiar bloku dobrany tak, żeby wartości mogły być przechowywane w rejestrach dla CPU i jednego wątku wiele zmiennych dla GPU np. jedna zmienna, ale wiele wątków 35

Przykład mnożenie macierzy int row = get_global_id(1); int local_row = get_local_id(1); float temp = 0.0; int col = get_global_id(0); int local_col = get_local_id(0); int nr_blocks = N/BLOCK_SIZE; for(iblock = 0; iblock < nr_blocks; iblock++){ A_local[local_row * BLOCK_SIZE + local_col] = A[row * N + iblock*block_size + local_col]; B_local[local_row * BLOCK_SIZE + local_col] = B[(local_row+iblock*BLOCK_SIZE) * N + col]; barrier(clk_local_mem_fence); for(i=0; i< BLOCK_SIZE; i++){ temp += A_local[local_row*BLOCK_SIZE+i] * B_local[i*BLOCK_SIZE+local_col]; } barrier(clk_local_mem_fence); } } C[row * N + col] = temp; 36