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



Podobné dokumenty
Paralelní programování

KTE/TEVS - Rychlá Fourierova transformace. Pavel Karban. Katedra teoretické elektrotechniky Fakulta elektrotechnická Západočeská univerzita v Plzni

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

VEKTORY. Obrázek 1: Jediný vektor. Souřadnice vektoru jsou jeho průměty do souřadných os x a y u dvojrozměrného vektoru, AB = B A

Transformace obrazu Josef Pelikán KSVI MFF UK Praha

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

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

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

Nvidia CUDA Paralelní programování na GPU

Matematika (CŽV Kadaň) aneb Úvod do lineární algebry Matice a soustavy rovnic

X37SGS Signály a systémy

MATURITNÍ OTÁZKY ELEKTROTECHNIKA - POČÍTAČOVÉ SYSTÉMY 2003/2004 PROGRAMOVÉ VYBAVENÍ POČÍTAČŮ

Management procesu I Mgr. Josef Horálek

SEMESTRÁLNÍ PRÁCE Z X37SAS Zadání č. 7

Operační systémy. Jednoduché stránkování. Virtuální paměť. Příklad: jednoduché stránkování. Virtuální paměť se stránkování. Memory Management Unit

0.1 Úvod do lineární algebry

Přidělování CPU Mgr. Josef Horálek

1 Základní funkce pro zpracování obrazových dat

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

[1] samoopravné kódy: terminologie, princip

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

Pokročilé architektury počítačů

SIGNÁLY A LINEÁRNÍ SYSTÉMY

Procesy a vlákna (Processes and Threads)

2. úkol MI-PAA. Jan Jůna (junajan)

Teorie informace a kódování (KMI/TIK) Reed-Mullerovy kódy

Jasové transformace. Karel Horák. Rozvrh přednášky:

Data v počítači. Informační data. Logické hodnoty. Znakové hodnoty

Jako pomůcka jsou v pravém dolním rohu vypsány binární kódy čísel od 0 do 15 a binární kódy příkazů, které máme dispozici (obr.21). Obr.

Co je grafický akcelerátor

Základní principy konstrukce systémové sběrnice - shrnutí. Shrnout základní principy konstrukce a fungování systémových sběrnic.

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

Úvod do zpracování signálů

Architektura počítačů

Osobní počítač. Zpracoval: ict Aktualizace:

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

Unity a Objekty (NMIN102) RNDr. Michal Žemlička, Ph.D.

" Furierova transformace"

Operační systémy 2: Zápočtové úkoly

0.1 Úvod do lineární algebry

INFORMAČNÍ A KOMUNIKAČNÍ TECHNOLOGIE

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

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

Pointery II. Jan Hnilica Počítačové modelování 17

SIGNÁLY A LINEÁRNÍ SYSTÉMY

II. Úlohy na vložené cykly a podprogramy

STRUKTURA RASTROVÝCH DAT

Architektura počítače

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

Paralelní výpočty ve finančnictví

Způsoby realizace této funkce:

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

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

Limita funkce. FIT ČVUT v Praze. (FIT) Limita funkce 3.týden 1 / 39

Základní komunikační operace

Princip funkce počítače

Architektura Intel Atom

11. Logické analyzátory. 12. Metodika měření s logickým analyzátorem

Matice přechodu. Pozorování 2. Základní úkol: Určete matici přechodu od báze M k bázi N. Každou bázi napíšeme do sloupců matice, např.

Vektory a matice. Obsah. Aplikovaná matematika I. Carl Friedrich Gauss. Základní pojmy a operace

Projektč.3dopředmětuIZP. Maticové operace

Vlákno (anglicky: thread) v informatice označuje vlákno výpočtu neboli samostatný výpočetní tok, tedy posloupnost po sobě jdoucích operací.

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

1 Linearní prostory nad komplexními čísly

MATLABLINK - VZDÁLENÉ OVLÁDÁNÍ A MONITOROVÁNÍ TECHNOLOGICKÝCH PROCESŮ

Maticí typu (m, n), kde m, n jsou přirozená čísla, se rozumí soubor mn veličin a jk zapsaných do m řádků a n sloupců tvaru:

Úvod do lineární algebry

PROCESOR. Typy procesorů

základní vlastnosti, používané struktury návrhové prostředky MATLAB problém kvantování koeficientů

1 Projekce a projektory

Kurz LSL skriptování. Shiny Iceberg 2009

31SCS Speciální číslicové systémy Antialiasing

Přidělování zdrojů (prostředků)

Systém adresace paměti

Matice. a m1 a m2... a mn

FOURIEROVA ANAL YZA 2D TER ENN ICH DAT Karel Segeth

Čísla, reprezentace, zjednodušené výpočty

Funkce a lineární funkce pro studijní obory

Bootkity v teorii a praxi. Martin Dráb martin.drab@ .cz

označme j = (0, 1) a nazvěme tuto dvojici imaginární jednotkou. Potom libovolnou (x, y) = (x, 0) + (0, y) = (x, 0) + (0, 1)(y, 0) = x + jy,

Matematika I (KMI/PMATE)

Zpracování obrazu v FPGA. Leoš Maršálek ATEsystem s.r.o.

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

Poznámka. V některých literaturách se pro označení vektoru také používá symbolu u.

VISUAL BASIC. Přehled témat

Lekce 01 Úvod do algoritmizace

Disková pole (RAID) 1

Česká letecká servisní a. s.

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

PB002 Základy informačních technologií

Paralelní programování

Matematika (KMI/PMATE)

Iterační výpočty Projekt č. 2

Funkce komplexní proměnné a integrální transformace

2 Postup při programování, úvod do programovacího jazyka Java

Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické

Algoritmus. Přesné znění definice algoritmu zní: Algoritmus je procedura proveditelná Turingovým strojem.

PROGRAMY PRO GIS. Formovat/formulovat problém pro aplikaci v počítači. Fungování GIS programů na základní úrovni - "uvažovat" jako počítač

1/1 ČESKÁ ZEMĚDĚLSKÁ UNIVERZITA V PRAZE PROVOZNĚ EKONOMICKÁ FAKULTA PŘIJÍMACÍ ŘÍZENÍ 2017/2018

VÝVOJ ŘÍDICÍCH ALGORITMŮ HYDRAULICKÝCH POHONŮ S VYUŽITÍM SIGNÁLOVÉHO PROCESORU DSPACE

Transkript:

V O J T Ě C H T E R Š 27.1.2013 INDIVIDUÁLNÍ PROJEKT 1 - ZPRACOVÁNÍ GNSS SIGNÁLU V GPU Ú K O L P R O J E K T U: Přeprogramování rychlé diskrétní Furierovy Transformace (FFT) do jazyka Open CL. V Y B R A N Á M E T O D A: Algoritmus Cooley-Tukey : Decimace v časové oblasti se základem 2. O ALGO R I T M U : Algoritmus vychází z definice Diskrétní Furierovy Transformace, která převádí ovzorkovaný vstupní signál o délce N vzorků z časové domény na frekvenční pomocí definičního vztahu: ( ) ( ). Kde j je imaginární jednotka, N počet prvků, k je index a n je násobek frekvence (0...N-1). Za předpokladu, že vstupem je reálný signál se sudým počtem vzorků, je jeho spektrum symetrické a komplexně sdružené kolem středu. Tzn. že reálná složka je sudá okolo středu a imaginární je lichá. Stačí tedy vypočíst první polovinu spektra, neboť ta druhá bude identická s opačným znaménkem u imaginární složky. Dostáváme : ( ) ( ) ( ) Přesněji: ( ) ( ) ( ). A po úpravě pak: ( ) ( ) Tedy : ( ) ( ) ( ) A: ( ) ( ) ( ) Pokud bychom takto postupovali dále a zkracovali neustále délku transformace (uvažujeme vstupní počet prvků 2 n ), dostaneme nakonec N/2 Transfomací 1. Řádu, tedy Diskrétních Furierových transformací o velikosti 2.Tomuto uspořádání odpovídá následující obrázek, kterému se kvůli jeho grafické podobě říká motýlek (Matematické operace nad těmito transformacemi ho skutečně připomínají) 1

1 ZDROJ:WIKIPEDIA.ORG Kde X (0) a X (1) jsou vstupní prvky a Y (0) a Y (1) jsou výstupní prvky. Přitom platí: Poslední výše zmíněný vztah se nazývá Twiddle Factor a reprezentuje rotaci v komplexní rovině. Přitom T je délka periody Twiddle factoru a k je jeho úhel. Z řešení vyplývá, že algoritmus bude celkem potřebovat provést N/2 * log2(n) motýlků (v každém kroku N/2 motýlků). Každý motýlek se přitom skládá ze 2 komplexních násobení a 2 komplexníxh sčítání. Pro DFT o velikosti 8 prvků vypadá pak postup následovně: 2ZDROJ: OPENCL PROGRAMMING BOOK Zde je třeba podotknout, že vstupní hodnoty jsou v bitově převráceném pořadí (Tzv. Bit Reversed Order). Vysvětlení celkem stručně vystihuje následující tabulka: Dekadický zápis pořadí Binární Zápis Bitová Inverze Nové Pořadí 0 000 000 0 1 001 100 4 2 010 010 2 3 011 110 6 4 100 001 1 5 101 101 5 6 110 011 3 7 111 111 7 2

K pochopení každého algoritmu však podle mne nejlépe přispěje nějaký příklad, takže se nyní pokusím spočítat pomocí výše uvedených vztahů FFT o 8 prvcích posloupnosti: 0...7 (Zcela správně by bylo prohodit vstupní hodnoty dle pravidel bitové inverze ): Vstupní hodnoty Motýlek 1 Motýlek 2 Motýlek 3 0+0*i 1+0*i 6+0*i 28+0*i 1+0*i -1+0*i -1+i -1+2,41*i 2+0*i 5+0*i -4+0*i -4+4*i 3+0*i -1+0*i -1-i -1+0,4142*I 4+0*i 9+0*i 22+0*i -16+0*i 5+0*i -1+0*i -1+i -1-0,4142*i 6+0*i 13+0*i -4+0i -4-4*i 7+0*i -1+0*i -1-i -1-2,4142*i Jednotlivé kroky jsou naznačeny na následujících obrázcích: Motýlek 1: Motýlek 2: 3

Motýlek 3: Ú V O D D O P R O S T Ř E D Í G R A F I C K É H O J Á D R A Většina dnešních početně náročných algoritmů se snaží využívat výpočetního výkonu grafický karet. Oproti klasickému používání algoritmů na procesoru (CPU Central Processing Unit) mají totiž grafická jádra (GPU Graphics Processign Unit ) mnohonásobně více pracovních vláken, která mohou pracovat nezávisle na sobě. Např. při sčítání dvou vektorů musí procesor s jedním vláknem postupovat od souřadnice k souřadnici a pokaždé tyto sečíst tedy jedná sekvenčně,tzn. vyhodnocuje operace po sobě. Naproti tomu GPU si může dovolit téměř vždy spustit tolik pracovních vláken, kolik má daný vektor souřadnic. Každé vlákno sečte odpovídající prvky a tím jsou vektory sečtěny. Vlákna tedy pracují paralelně nezávisle na sobě. Většina dnešních GPU má přitom k dispozici 1024-2048 pracovních vláken na jeden blok, který můžeme chápat jako skupinu vláken se společnými hardwarovými prostředky (například společnou lokální pamětí). Každé jádro zároveň může spouštět zhruba stejný počet pracovních bloků a to dokonce ve 3 dimenzích, což dohromady může dát i miliony pracovních vláken. Každé vlákno má přitom svůj vlastní index (unikátní v rámci celé pracovní mříže vláken a bloků). Proto není problém,,přemapovat daná vstupní data na určitou pracovní jednotku, která s nimi dále bude pracovat. Spouštění těchto algoritmů má však i některé nevýhody, které nejsou běžně vidět: vstupní data se obvykle nachází na straně CPU a je třeba je nejprve překopírovat do paměti GPU, tam je zpracovat a překopírovat zpět na CPU. Dnešní rychlosti sběrnic jsou sice vysoké, ale i tak jsou ve srovnání s výkonem grafických karet několikanásobně menší. Krom toho musíme brát v úvahu i fakt, že globální paměť na GPU (ač je opět velmi rychlá) má omezenou rychlost a většina čtecích a zapisovacích operací bude omnoho pomalejší, než například při použití lokální paměti v rámci jednotlivých bloků. Při navrhování algoritmu tedy musíme dávat především pozor na zbytečné kopírování a zbytečné zatěžování globální paměti. Ani tak ale situce není zcela optimalizovaná. Ideální programátor by si také měl uvědomit, že globální a lokální paměť využívá tzv. banky, do kterých jednotlivá vlákna přistupují při čtení/zapisování hodnot a že i tyto přístupy lze optimalizovat. K samotnému obecnému popisu algoritmů, běžících na straně GPU, pak slouží kernely. To jsou části kódu, které obsahují všechny potřebné informace pro výpočet; je v nich definováno, kolik se má spustit bloků a pracovních jednotek v rámci jednoho bloku, dále v jakých dimenzích, jak se mají přemapovat vstupní data a co které vlákno má v danou chvíli dělat. Z hlediska programování si musíme uvědomit, že paralelní implementace není tak jednoduchá, jak by se mohlo zdát i přes všechny výhody, které jsme popsali. Žádný jazyk totiž nemá definováno, jestli se například při použití obecných hodnot vlákna, která je měla zpracovávat, už dobrala 4

k výsledku. Tedy klidně se může stát, že některá vlákna mohou používat při špatné synchronizaci i nepravdivé a dokonce nesmyslné výsledky. Tomu se dá zabránit například synchronizací vláken, kdy všechna vlákna, která už zpracovala svou část kódu, čekají na zbývající. Pak opět pokračují všechna stejně, dokud se nedostanou k další synchronizační bariéře. Nicméně je dobré podoknout, že takto popsaná synchronizace funguje jen v rámci jednoho bloku a nikoliv v rámci celé výpočetní mřížky. Jinými slovy, neexistuje dostatečně vhodný způsob, jak zajistit, aby se synchronizovala všechna vlákna v rámci celého GPU. Metody, které by to zvládly, by byly z hlediska GPU časově náročné. Zde je skromné porovnání toho, jaký může mít vliv jeden klíčový synchronizační úsek kódu: Bez synchronizace vláken: 5

Se synchronizací vláken: I M P L E M E N T A C E ALGORI T M U Samotná Implementace spočívá v tom nejprve zinverzovat vstupní hodnoty a v průběhu algoritmu pak pokaždé správně načíst 2 odpovídající hodnoty počítaného motýlka (dle cyklu, ve kterém se nachází), správně spočítat Twiddle Factor a poté dle dalších pravidel zapsat výsledek pro další výpočet. Z výše zmíněných synchronizačních důvodů jsem řešil problém,jak správě navrhnout algoritmus? Buď bude rychlý a bude mít malý rozsah vstupních hodnot, a nebo bude pomalejší, ale bude moci zpracovávat velká množstí vstupních prvků. Nakonec jsem raději navrhl oba algoritmy jak v jazyce CUDA, tak v OpenCL. První zmíněný přitom využívá pracovních jednotek (vláken) jen v rámci jednoho bloku, kde je možná synchronizace a tedy celou for smyčku (jejíž velikost odpovídá log2(n)) je možné provádět přímo na GPU. Druhý algoritmus přitom neustále spouští nové kernely pro každou fázi výpočtu konkrétně 2 na jednu fázi. Toto spouštění samozřejmě neproběhne hned a má za následek nižší rychlost výpočtu. Krom toho je v každé fázi nutné spustit kernel s jinými parametry (vlastě konkrétně s jedním), nicméně se opět jedná o kopírování, které není moc efektivní. Při porovnávání rychlosti vykazovala tato druhá verze algoritmu při stejném vstupním počtu prvků (N=512) zhruba pětinásobnou časovou náročnost v jazyce CUDA. Samotné počítání s komplexními čísly jsem řešil následovně: ( ) ( ) { } { } Pro indexování jsem nejprve musel ověřit (pro případ, že by bylo spuštěno více vláken, než je vstupních prvků), že dané vlákno skutečně může počítat část FFT. Poté přišla na řadu otázka indexování aktivních vlláken (která jsou v dané fázi výpočtu aktivní). S tím jsem si poradil pomocí funkce modulo. Dá se ověřit, že pokud mám na začátku proměnnou a = 2 a v každém cyklu ji 6

vynásobím opět dvojkou, pak je dané vlákno aktivní jestliže platí: (tid % a) >=(a/2). Kde tid je index vlákna. Fáze 1 2 3 Aktivní Tid % 2 = 1 Tid % 4 = 2,3 Tid % 8 = vlákna 4,5,6,7 Pro periodu Twiddle faktoru platí, že v každém dalším kroku je dvojnásobná a není tedy třeba ji nějak zvláště přepočítávat. Pokud bychom si navíc nakreslili diagram počítání FFT pro 8 hodnot, je zřejmé, že vstupní hodnoty každého motýlka jsou vzdáleny o a/2. (1,2,4,8...). Nejsložitější bylo pravděpodobně vhodně přeindexovat úhel Twiddle Factoru. Nicméně uvedu na příkladě: Mod 2 4 8 16 Tid = 15 1 3 7 15 Potřebný index k 0 1 3 7 Z tabulky je patrné, že v první fázi je index vždy 0 (řešeno explicitně pro všechna vlákna). V dalších fázích je však možno k spočítat následovně: k = (tid % (a/2)). Vzhledem k tomu, že zadáním projektu však bylo navrhnout algoritmus v jazyce OpenCL, a nikoliv v jazyce CUDA, nezbývá než uvést na závěr stručný přepis daného algoritmu z CUDA do OpenCl. Jelikož oba jazyky fungují na stejné paralelní platformě, zachová se naprostá většina (asi 90%) kódu, běžícího na GPU - kernelů. V daném případě je rozdíl zřejmě jen v tom, že ve zdrojových souborech kernelů jazyka OpenCl nemohou být komentáře (k velké nelibosti programátora). Naprostá většina změn tedy proběhne v kódu na CPU, kde OpenCl vyžaduje následující postup: 1. Výběr platformy 2. Výběr zařízení 3. Vytvoření kontextu 4. Vytvoření fronty příkazů 5. Vytvoření paměťových zásobníků 6. Načtení všech kernelů 7. Vytvoření programu 8. Kompilace programu 9. Vytvoření objektů všech kernelů 10. Nastavení parametrů kernelů 11. Překopírování dat do zařízení 12. Spuštění kernelu 13. Překopírování výsledků 14. Uvolnění používaných prostředků 7

Tato zdlouhavá procedura má za následek špatnou orientaci v kódu (ve kterém naštěstí komentáře být mohou), větší výskyt chyb a samozřejmě několikanásobně delší kód.pro srovnání s jazykem CUDA: 1. Alokování paměti na GPU 2. Kopírování vstupních dat 3. Spuštění kernelu 4. Překopírování výsledků 5. Uvolnění prostředků Což je důvod prvotní implementace algoritmu v jazyce CUDA, kde se rovněž i snáze měří čas potřebný ke spočtení FFT. Má implementovaná verze v OpenCL vybere první dostupnou platformu a první dostupný grafický procesor (ač obecně se dá OpenCl spouštět i na vícejaderném procesoru). Následně si vytvoří paměťové objekty, načte zdrojový kód kernelů (který zároveň i zobrazí), vytvoří a překompiluje program (v případě chyby je uvedena v příkazovém řádku), vytvoří požadované kernely, překopíruje vstupní data a následně spustí kernely, po jejichž ukončení následuje nezbytné překopírování výsledků a uvolnění použitých prostředků. Závěrem práce bych doporučil používat CUDA místo OpenCL. P O U Ž I T Á LI T E R A T U R A: OpenCLProgramming Guide (Aaftab Munshi, Bnedict Gaster,Timothy Mattson, James Fung, Dan Ginsburg) The OpenCl Programming Book (Ryoji Tsuchiyama, Takashi Nakamura, Takuro Iizuka, Akihiro Asahara, Jeongdo Son, Satoshi Miki) Cuda Application Design And Developement (Rob Farber) Cuda By Example An Introduction to General-Purpose GPU Programming (Jason Sanders, Edward Kandrot) nvidia CUDA C Programming Guide 8