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

Podobne dokumenty
Programowanie Współbieżne

Programowanie kart graficznych

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

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

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

Programowanie aplikacji równoległych i rozproszonych

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

Programowanie CUDA informacje praktycznie i. Wersja

Programowanie procesorów graficznych w CUDA.

Programowanie procesorów graficznych GPGPU

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

CUDA. cudniejsze przyk ady

Programowanie kart graficznych

Procesory kart graficznych i CUDA wer

Tesla. Architektura Fermi

Przetwarzanie Równoległe i Rozproszone

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

Programowanie procesorów graficznych GPGPU

Programowanie CUDA informacje praktycznie i przykłady. Wersja

Obliczenia na GPU w technologii CUDA

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

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

CUDA ćwiczenia praktyczne

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

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

i3: internet - infrastruktury - innowacje

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

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

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

Moc płynąca z kart graficznych

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

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

Programowanie z wykorzystaniem technologii CUDA i OpenCL Wykład 1

Procesory kart graficznych i CUDA wer PR

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

Procesory kart graficznych i CUDA

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

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

Procesory kart graficznych i CUDA wer

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

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

GTX260 i CUDA wer

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

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

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

Przygotowanie kilku wersji kodu zgodnie z wymogami wersji zadania,

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

ZARZĄDZANIE PAMIĘCIĄ W TECHNOLOGII CUDA

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

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

MMX i SSE. Zbigniew Koza. Wydział Fizyki i Astronomii Uniwersytet Wrocławski. Wrocław, 10 marca Zbigniew Koza (WFiA UWr) MMX i SSE 1 / 16

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

Organizacja pamięci w procesorach graficznych

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

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

Podstawy programowania komputerów

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

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

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

PROE wykład 9 C++11, rzutowanie, optymalizacja. dr inż. Jacek Naruniec

Obliczenia Wysokiej Wydajności

16. Taksonomia Flynn'a.

Programowanie GPU jako procesora ogólnego przeznaczenia.

ROZPROSZONY SYSTEM DO KRYPTOANALIZY SZYFRÓW OPARTYCH NA KRZYWYCH ELIPTYCZNYCH

Programowanie kart graficznych. Sprzęt i obliczenia

Zaawansowane programowanie w języku C++ Zarządzanie pamięcią w C++

Hybrydowy system obliczeniowy z akceleratorami GPU

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

Klasyfikacja systemów komputerowych. Architektura von Neumanna Architektura harwardzka Zmodyfikowana architektura harwardzka. dr inż.

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

dr inż. Jarosław Forenc

Obliczenia Wysokiej Wydajności

HPC na biurku. Wojciech De bski

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

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

Język ludzki kod maszynowy

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

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

Programowanie współbieżne Wykład 2. Iwona Kochańska

Implementacja modelu FHP w technologii NVIDIA CUDA

Przetwarzanie Równoległe i Rozproszone

Architektura komputerów

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

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

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

Linux Kernel III. Character devices

Wykorzystanie architektury Intel MIC w obliczeniach typu stencil

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

CUDA jako platforma GPGPU w obliczeniach naukowych

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

Szablony funkcji i szablony klas

Wykład Ćwiczenia Laboratorium Projekt Seminarium

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

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

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

Praca dyplomowa magisterska

Zastosowanie technologii nvidia CUDA do zrównoleglenia algorytmu genetycznego dla problemu komiwojażera

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

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

Wykład 14. Zagadnienia związane z systemem IO

Transkrypt:

CUDA obliczenia ogólnego przeznaczenia na mocno zrównoleglonym sprzęcie W prezentacji wykorzystano materiały firmy NVIDIA (http://www.nvidia.com) 1

Architektura karty graficznej W porównaniu z tradycyjnym procesorem karta graficzna ma stosunkowo prosty moduł kontrolny, który jest silnie zrównoleglony. Dodatkową cechą charakterystyczną jest duża liczba jednostek obliczeniowych i relatywnie mniej pamięci cache.

Potencjał obliczeniowy Uwaga: rysunek przedstawia TEORETYCZNE możliwości sprzętu.

Przepustowość pamięci Uwaga: rysunek przedstawia TEORETYCZNE możliwości sprzętu.

Wady i zalety Zalety Bardzo dobry stosunek ceny do (potencjalnej) szybkości. Szybki rozwój sprzętu. Rozwojowa technologia. Wady Konieczność przepisania kodu problem przenośności. Uzyskanie rzeczywistej wydajności zbliżonej do teoretycznych możliwości sprzętu wymaga dużo pracy.

Technologie CUDA (od Compute Unified Device Architecture) platforma programistyczna i model programowania stworzony przez firmę NVIDIA. (C/C++, Fortran,...) OpenCL (Open Computing Language) szkielet do aplikacji na heterogenicznych platformach z CPU, GPU, DSP. (Język oparty o C99 i API). DirectCompute API dla Windows (Vista, 7, 8) wspierane przez Microsoft, część DirectX.

Dojrzałość CUDA wydaje się być rozwiązaniem najbardziej dojrzałym: powstała w 2006 roku (15.02.2007 upubliczniona dla MS Windows i Linuksa); obecna wersja to 5.0 (październik 2012); wsparcie dla wielu języków; zaimplementowane liczne biblioteki.

CUDA Specyfikacja architektury urządzenia pozwala wprowadzić drobnoziarnistą równoległość danych (Pcam) wątki, pozwala zoptymalizować współpracę wątków (pcam) grupy wątków, pozwala transparentnie mapować strukturę programu na architekturę urządzenia (pcam). Model programistyczny zbiór rozszerzeń/restrykcji/konwencji dla języków programowania, biblioteki.

Streaming Multiprocesor SM podstawowa jednostka architektury karty 8 skalarnych procesorów, wszystkie mogą działać (lub spać) równocześnie, przydział instrukcji za darmo, do 32 wątków (warp) wykonywanych na raz przez SM (w 4 cyklach zegara), do 24 aktywnych warpów w jednym SM, wątki współdzielą część pamięci, każdy wątek ma własną pamięć rejestrową.

Architektura GPU dla programu CPU

Skalowalność Użytkownik (programista) projektuje sieć wątków dopasowaną do danych. Sprzęt (karta) dopasowuje bloki do aktualnej architektury.

Przykład (1) oer:~/downloads/nvidia_cuda 5.0_Samples/bin/linux/release>./deviceQuery [...] Device 0: "GeForce 9800 GT" CUDA Driver Version / Runtime Version 5.0 / 5.0 CUDA Capability Major/Minor version number: 1.1 Total amount of global memory: 1023 MBytes (1073020928 bytes) (14) Multiprocessors x ( 8) CUDA Cores/MP: 112 CUDA Cores GPU Clock rate: 1500 MHz (1.50 GHz) Memory Clock rate: 900 Mhz Memory Bus Width: 256 bit Max Texture Dimension Size (x,y,z) 1D=(8192), 2D=(65536,32768), 3D=(2048,2048,2048) Max Layered Texture Size (dim) x layers 1D=(8192) x 512, 2D=(8192,8192) x 512 Total amount of constant memory: 65536 bytes Total amount of shared memory per block: 16384 bytes Total number of registers available per block: 8192 Warp size: 32 Maximum number of threads per multiprocessor: 768 Maximum number of threads per block: 512 Maximum sizes of each dimension of a block: 512 x 512 x 64 Maximum sizes of each dimension of a grid: 65535 x 65535 x 1 Maximum memory pitch: 2147483647 bytes Texture alignment: 256 bytes Concurrent copy and kernel execution: Yes with 1 copy engine(s) Run time limit on kernels: Yes Integrated GPU sharing Host Memory: No Support host page locked memory mapping: Yes Alignment requirement for Surfaces: Yes Device has ECC support: Disabled Device supports Unified Addressing (UVA): No Device PCI Bus ID / PCI location ID: 1 / 0 [...] 1: Tesla

Przykład (2) [jstar@n2 ~/cuda/bin/linux/release]./devicequery [...] Detected 4 CUDA Capable device(s) Device 0: "Tesla C2070" CUDA Driver Version / Runtime Version 5.0 / 5.0 CUDA Capability Major/Minor version number: 2.0 Total amount of global memory: 5375 MBytes (5636554752 bytes) (14) Multiprocessors x ( 32) CUDA Cores/MP: 448 CUDA Cores GPU Clock rate: 1147 MHz (1.15 GHz) Memory Clock rate: 1494 Mhz Memory Bus Width: 384 bit L2 Cache Size: 786432 bytes Max Texture Dimension Size (x,y,z) 1D=(65536), 2D=(65536,65535), 3D=(2048,2048,2048) Max Layered Texture Size (dim) x layers 1D=(16384) x 2048, 2D=(16384,16384) x 2048 Total amount of constant memory: 65536 bytes Total amount of shared memory per block: 49152 bytes Total number of registers available per block: 32768 Warp size: 32 Maximum number of threads per multiprocessor: 1536 Maximum number of threads per block: 1024 Maximum sizes of each dimension of a block: 1024 x 1024 x 64 Maximum sizes of each dimension of a grid: 65535 x 65535 x 65535 Maximum memory pitch: 2147483647 bytes Texture alignment: 512 bytes Concurrent copy and kernel execution: Yes with 2 copy engine(s) Run time limit on kernels: No Integrated GPU sharing Host Memory: No Support host page locked memory mapping: Yes Alignment requirement for Surfaces: Yes Device has ECC support: Enabled Device supports Unified Addressing (UVA): Yes Device PCI Bus ID / PCI location ID: 2 / 0 [...] 2: Fermi

CUDA Kernel Kernel (jądro) to specjalna funkcja, która może być uruchomiona przez wiele wątków na raz. Strukturę sieci wątków używanej do uruchomienia kernela określa się w momencie jego wywołania.

Przykład kernela W powyższym przykładzie kernel VecAdd jest uruchamiany na liniowej strukturze N wątków. Numer wątku jest dostępny wewnątrz kernela przy pomocy struktury (dim3) threadidx

Struktura wątków Zmienna threadidx ma trzy wymiary (x,y,z) do pozwala naturalnie rozpraszać obliczenia dla danych 1D, 2D i 3D Zmienna threadidx indeksuje wątki w ramach bloku, którego maksymalna wielkość nie może obecnie przekraczać 1024 (starsze karty mogą pozwalać na mniej). W ramach bloku wątki są numerowane zgodnie z zasadą x+y Dx + z Dx Dy

Przykład 2D

Sieć bloków wątków Bloki wątków można organizować w sieci. Kernel może zostać uruchomiony na dowolnej sieci bloków o identycznym kształcie. Podobnie jak blok, także i sieć może być 1-, 2- lub 3wymiarowa. Numer bloku jest dostępny wewnątrz kernela przez zmieną (strukturę dim3) blockidx.

Przykład sieci bloków (1) 256 (16x16) wątków w bloku, N/16 x N/16 = N2/256 bloków = 1 wątek na element tablicy.

threadidx.x blockdim.x blockdim.y Przykład sieci bloków (2) Bloki są wykonywane niezależnie, w dowolnym porządku, równolegle lub sekwencyjnie. Wątki w bloku współdzielą część pamięci (szybkiej). Wątki w bloku można synchronizować (lekka bariera).

Pamięć Wątki mogą korzystać z kilku obszarów pamięci: Każdy wątek ma przydzieloną prywatną pamięć lokalną Każdy blok wątków ma przydzielony wspólny obszar pamięci Wszystkie sieci wątków mogą korzystać z obszaru pamięci globalnej Wszystkie sieci wątków mogą też czytać pamięć stałą i pamięć tekstur.

Model programu Model programu CUDA przypomina trochę model OpenMP: części równoległe wykonywane na urządzeniu CUDA przeplatają się z kodem sekwencyjnym wykonywanym przez procesor. Urządzenie CUDA można traktować jako ko-procesor posiadający własną pamięć. Kopiowanie danych pomiędzy pamięcią procesora i pamięcią karty może być wąskim gardłem programu.

Program Pamięć karty może być dostępna na dwa sposoby. Przy pierwszym (dostęp liniowy) jest alokowana przez cudamalloc i zwalniana za pomocą cudafree. Adres jest 32b dla urządzeń 1.x i 40b dla urządzeń 2.x i nowszych (można używać wskaźników pomiędzy adresami). Kopiowanie danych na/z urządzenia za pomocą cudamemcpy.

Kompilacja (JIT)

Efektywność (szybkość) Maksymalizacja zrównoleglenia Aplikacja (w miarę możliwości asynchronicznie) Urządzenie CUDA (liczba bloków == liczba MP, użycie strumieni) Multiprocesor (aktywne warpy) Optymalizacja dostępu do pamięci Jak najmniej transferów host urządzenie Użycie szybkiej pamięci (shared, cache) Dopasowanie danych do struktury pamięci Optymalizacja użycia instrukcji Użycie lekkich instrukcji/funkcji Minimalizacja zróżnicowania wątków Minimalizacja zróżnicowania używanych instrukcji

Zrównoleglenie aplikacja Równoległe działanie hosta i urządzenia Nakładanie transferu danych i kerneli Równoległy transfer danych Strumienie Zdarzenia

Równoległe działanie hosta i urządzenia Następujące funkcje są wykonywane asynchronicznie Uruchamianie kerneli Kopiowanie danych w ramach jednego urządzenia Kopiowanie host urządzenie porcji danych <64kB Asynchroniczne funkcje kopiujące (xxxasync) Ustawianie wartości w pamięci Kernele uruchamiane są synchronicznie pod debuggerem, profilerem, przy kontroli pamięci i na urządzeniach 1.x. Można zablokować asynchroniczne uruchamianie kerneli przez ustawienie zmiennej środowiskowej CUDA_LAUNCH_BLOCKING=1

Równoległe działanie urządzenia w skali makro (1) Od urządzeń 1.1 kopiowanie danych z/na host może być wykonywane równolegle z wykonywaniem kerneli. Można sprawdzić, czy urządzenie umożliwia to przez wartość właściwości asyncenginecount (0 nie, dodatnie tak). W urządzeniach 1.x dotyczy to tylko liniowych danych. Od urządzeń 2.x wiele urządzeń potrafi kopiować z i na urządzenie równolegle. Można sprawdzić, czy urządzenie umożliwia to przez wartość właściwości asyncenginecount (2 i więcej tak).

Równoległe działanie urządzenia w skali makro (2) Od urządzeń 2.x wiele kerneli może być uruchamianych równolegle na tym samym urządzeniu. Można sprawdzić, czy urządzenie umożliwia to przez wartość właściwości concurrentkernels (1 tak). Liczba równoległych kerneli jest ograniczona do 16 (32 dla urządzeń 3.5 i nowszych). Ograniczeniem może też być pamięć używana przez kernel. Wszystkie rónoległe kernele muszą należeć do tego samego kontekstu (CUDA context ~ proces dla CPU).

Strumienie Strumień (stream) to sekwencja poleceń. Domyślnie istnieje jeden strumień o numerze 0. Można tworzyć dodatkowe strumienie i używać ich numerów, tworząc w ten sposób równoległe sekwencje poleceń.

Strumienie przykład (1) Dwa strumienie, każdy z nich kopiuje z hosta na urządzenie size danych, uruchamia MyKernel dla swoich danych, kopiuje dane na host. Ten kod będzie działał na kartach, które obsługują równoległy transfer danych.

Synchronizacja strumieni Jawna zestaw funkcji cudadevicesynchronize() cudastreamsynchronize() cudastream WaitEvent() cudastreamquery() Niejawna Alokacja pamięci na hoscie (cudamalloc) Alokacja/zapis/kopiowanie na urządzeniu Polecenie CUDA dla strumienia 0 Zmiana konfiguracji pamięci w urządzeniach 2.x

Wywołania wsteczne Funkcja MyCallback zostanie uruchomiona po zakończeniu wszystkich operacji na strumieniu uruchomionych przed rejestracją wywołania wstecznego.

Zdarzenia Zdarzenia są rejestrowane asynchronicznie w strumieniach Zdarzenia są kończone w momencie, gdy skończą się wszystkie zadania i komendy strumienia poprzedzające rejestrację zdarzenia. Zdarzenia w strumieniu 0 są kończone, gdy skończą się wszystkie zadania i komendy we wszystkich strumieniach.

Strumienie przykład (2) Dwa strumienie, każdy z nich kopiuje z hosta na urządzenie size danych, uruchamia MyKernel dla swoich danych, kopiuje dane na host. Ten kod będzie działał na kartach, które obsługują równoległy transfer danych i działanie kerneli.

Optymalizacja dostępu do pamięci urządzenia Pamięć współdzielona przez blok jest znacznie szybsza, niż pamięć globalna. Odpowiednia organizacja wątków i wykorzystanie pamięci współdzielonej może bardzo znacznie przyspieszyć kod.

Mnożenie macierzy (1)

Mnożenie macierzy (2.1)

Mnożenie macierzy (2.2)

Naiwnie Pamięć współdzielona

Transpozycja macierzy (1) #define NN (4096) int main(int args, char** vargs) { const int HEIGHT = NN; const int WIDTH = NN; const int SIZE = WIDTH * HEIGHT * sizeof(float); cudaevent_t start, stop; cudaeventcreate(&start); cudaeventcreate(&stop); dim3 blockdim(block_dim,block_dim); dim3 griddim(width / blockdim.x, HEIGHT / blockdim.y); float* m = (float*)malloc(size); float* md = NULL; cudaeventrecord(start, 0); cudamalloc((void**)&md, SIZE); cudamemcpy(md, m, SIZE, cudamemcpyhosttodevice ); float* td = NULL; cudamalloc((void**)&td, SIZE); global void transpose_naive(float *odata, float* idata, int w, int h) { unsigned int x = blockdim.x * blockidx.x + threadidx.x; unsigned int y = blockdim.y * blockidx.y + threadidx.y; if (x < w && y < h ) { transpose_naive<<<griddim, blockdim>>>(td, md, WIDTH, HEIGHT); unsigned int idx_in = x + w * y ; unsigned int idx_out = y + h * x; odata[idx_out] = idata[idx_in]; cudamemcpy(m, td, SIZE, cudamemcpydevicetohost); } } cudaeventrecord(stop, 0); cudaeventsynchronize(stop); float elapsedtime; cudaeventelapsedtime(&elapsedtime, start, stop); cudaeventdestroy(start); cudaeventdestroy(stop); 363.791 ms printf( "Time=%g\n", elapsedtime ); return 0; }

Transpozycja macierzy (2) global void transpose(float *odata, float *idata, int w, int h) { shared float block[block_dim][block_dim+1]; // read the matrix tile into shared memory unsigned int x = blockidx.x * BLOCK_DIM + threadidx.x; unsigned int y = blockidx.y * BLOCK_DIM + threadidx.y; if((x < w ) && (y < h )) { unsigned int index_in = y * w + x ; block[threadidx.y][threadidx.x] = idata[index_in]; } syncthreads(); // write the transposed matrix tile to global memory x = blockidx.y * BLOCK_DIM + threadidx.x; y = blockidx.x * BLOCK_DIM + threadidx.y; if((x < h ) && (y < w )) { unsigned int index_out = y * h + x ; odata[index_out] = block[threadidx.x][threadidx.y]; } }

Transpozycja macierzy (3) global void transpose(float *odata, float *idata, int w, int h) { shared float block[block_dim][block_dim+1]; // read the matrix tile into shared memory unsigned int x = blockidx.x * BLOCK_DIM + threadidx.x; unsigned int y = blockidx.y * BLOCK_DIM + threadidx.y; if((x < w ) && (y < h )) { unsigned int index_in = y * w + x ; block[threadidx.y][threadidx.x] = idata[index_in]; } syncthreads(); // write the transposed matrix tile to global memory x = blockidx.y * BLOCK_DIM + threadidx.x; y = blockidx.x * BLOCK_DIM + threadidx.y; if((x < h ) && (y < w )) { unsigned int index_out = y * h + x ; odata[index_out] = block[threadidx.x][threadidx.y]; } } 137.592 ms

Transpozycja na różnych zdolności obliczeniowych oer:~/pliki/dydaktyka/prir/prir/programy/cuda>./a.out 0 1 2 3 4 5 6 7 8 9 Time of copy kernel=3.26445 Time of transpose_naive kernel=246.948 Time of transpose kernel=19.1968 0 4096 8192 12288 16384 20480 24576 28672 32768 36864 oer:~/pliki/dydaktyka/prir/prir/programy/cuda> [jstar@n1 ~/mycuda]./a.out 0 1 2 3 4 5 6 7 8 9 Time of copy kernel=1.74317 Time of transpose_naive kernel=2.92221 Time of transpose kernel=2.06314 0 4096 8192 12288 16384 20480 24576 28672 32768 36864 [jstar@n1 ~/mycuda] Tesla (1.1) Fermi (2.0)