Kompresja falkowa w środowisku NVIDIA CUDA

Wielkość: px
Rozpocząć pokaz od strony:

Download "Kompresja falkowa w środowisku NVIDIA CUDA"

Transkrypt

1 Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych Instytut Informatyki Rok akademicki 2010/2011 Praca dyplomowa inżynierska Stanisław Ogórkis Kompresja falkowa w środowisku NVIDIA CUDA Opiekun pracy: mgr inż. Julian Myrcha Ocena Podpis Przewodniczącego Komisji Egzaminu Dyplomowego

2 Specjalność: Informatyka Inżynieria systemów informatycznych Data urodzenia: 15 lutego 1988 r. Data rozpoczęcia studiów: 1 października 2007 r. Życiorys Nazywam się Stanisław Ogórkis i urodziłem się 15 lutego 1988 r. w Suwałkach. Po ukończeniu gimnazjum, kontynuowałem naukę w I L.O. im. Marii Konopnickiej w Suwałkach. W szkole średniej uczęszczałem do klasy o profilu matematyczono-fizycznym. W październiku 2007 r. rozpocząłem studia na Wydziale Elektroniki i Technik Informacyjnych Politechniki Warszawskiej podpis studenta Egzamin dyplomowy Złożył egzamin dyplomowy w dn Z wynikiem Ogólny wynik studiów Dodatkowe wnioski i uwagi Komisji

3 Streszczenie Głównym celem pracy jest zaimplementowanie kompresora obrazów i sekwencji wideo wykorzystującego transformatę falkową. Ponadto wykorzystana jest technologia NVIDIA CUDA pozwalająca na wykonywanie obliczeń na procesorze karty graficznej. Zaprezentowane są algorytmy związane z transformatą falkową, kwantyzacją i kodowaniem arytmetycznym. W pracy przedstawione są podstawy platformy NVIDIA CUDA. Szczególny nacisk położony jest na możliwości realizacji części algorytmów na procesorze graficznym. Wykonany koder jest zweryfikowany pod kątem efektywności implementacji GPU. Słowa kluczowe: transformata falkowa, falki, kompresja stratna, kwantyzacja, cuda. Abstract Title: Wavelet compression in NVIDIA CUDA. The main goal of this thesis is to implement image and video sequence wavelet compressor. The compressor is implemented using NVIDA CUDA technology which allows computing on GPU. The algorithms for wavelet transform, quantization and arithmetic coding are presented. The thesis describes basics of the NVIDA CUDA architecture. The particular emphasis is placed on the feasibility of the algorithms on the GPU. Created encoder is verified for GPU implementation effectiveness. Key words: wavelet transform, wavelets, lossy compression, quantization, cuda.

4 Spis treści 1 Wstęp Zdefiniowanie problemu Cele pracy Zawartość pracy Transformata falkowa Informacje ogólne Funkcja falkowa Realizacja dyskretnej transformaty falkowej przy użyciu filtrów Przykład obliczenia transformaty i transformaty odwrotnej Współczynniki filtrów falkowych Transformata sygnałów wielowymiarowych Algorytm konwolucji Metody kwantyzacji Skalarna kwantyzacja równomierna Skalarna kwantyzacja nierównomierna Skalarna kwantyzacja równomierna z rozszerzonym przedziałem zerowym Kodowanie arytmetyczne Kodowanie arytmetyczne oparte o arytmetykę rzeczywistoliczbową Przykład Kodowanie arytmetyczne oparte o arytmetykę całkowitoliczbową Koder adaptacyjny Technologia NVIDIA CUDA Efektywność obliczeniowa procesorów graficznych Model programowania Funkcje kerneli Hierarchia wątków Hierarchia pamięci Opis proponowanego rozwiązania Wymagania dotyczące aplikacji Funkcje aplikacji

5 6.3 Architektura rozwiązania Implementacja projektu Platforma sprzętowa Narzędzia i biblioteki Algorytm obliczania transformaty falkowej na procesorze GPU Mechanizmy pomiaru czasu Weryfikacja Zbiór testowy Precyzja obliczeń Efektywność kompresji Szybkość działania Podsumowanie

6 1 Wstęp 1.1 Zdefiniowanie problemu Uzyskanie możliwie najkrótszej reprezentacji danych jest głównym kryterium stosowanym przy ocenie algorytmów kompresji. Wraz z rozwojem technik multimedialnych oraz wykorzystania komputerów w medycynie oraz inżynierii, wzrosło zapotrzebowanie na skuteczne kompresowanie obrazów i sekwencji wideo. Metody bezstratne umożliwiają dla typowych obrazów uzyskiwanie współczynników kompresji do około 4 : 1. Aby uzyskać krótszą reprezentację wykorzystujemy algorytmy, które nie gwarantują jednakowego odtworzenia skompresowanych danych. Wówczas poza kryterium stopnia kompresji i szybkości działania ważna staje się jakość odtworzonych danych. Przez lata powstał szereg metod stratnej kompresji danych. Ich główna idea opiera się na odrzuceniu tych informacji, które są najmniej istotne dla odbiorcy. Dzięki temu w kolejnych krokach możemy skuteczniej kompresować dane przy użyciu standardowych algorytmów kompresji bezstratnej. Powszechnie stosowane algorytmy wykorzystują transformaty, które zmieniają dziedzinę danych na taką gdzie energia sygnału koncentruje się w mniejszej liczbie współczynników niż ma to miejsce w pierwotnej reprezentacji [2] [10]. Na przykład, po zastosowaniu transformaty kosinusowej dla bloków 8x8 obrazu w standarcie JPEG, energia sygnału kumuluje się lewej górnej części macierzy współczynników. Kwantyzacja uzyskanych współczynników jest krokiem, który decyduje o jakości odtworzonych danych. W tym kroku selektywnie rezygnujemy z części danych, aby uzyskać uproszczoną reprezentację, która lepiej poddaje się kompresji bezstratnej. Najnowsze algorytmy kompresji (JPEG2000, REDCODE) jako transformatę wykorzystują funkcje falkowe. Pierwszą funkcję falkową opisał na początku XX wieku Haar, ale wstępne próby ich zastosowania do kompresji pojawiły się dopiero po pracach Ingrid Daubechies [4] oraz Stéphane Mallat [9]. Transformata falkowa umożliwia wielokrotnie powtarzaną dekompozycję danych na składowe wysoko i niskoczęstotliwościowe. Dzięki temu na niewielkiej liczbie współczynników możemy skoncentrować większość energii sygnału związanej z pasmem niskoczęstotliwościowym. Równie ważną cechą jest separowalność funkcji falkowych, która umożliwia liczenie transformat wielowymiarowych przez odpowiednie złożenie transformat jednowymiarowych. Wyznaczenie współczynników transformaty dla przypadku danych więcej niż dwuwymiarowych wymaga znacznych nakładów obliczeniowych. Przy ciągłym rozwoju grafiki komputerowej, współczesne akceleratory graficzne posiadające setki rdzeni uzyskały większą moc obliczeniową niż jednostki centralne. Udostępnione na początku 2007 roku API NVIDIA CUDA umożliwia programowanie karty graficznej do wykonywania obliczeń (GPU Computing). Kompresja falkowa bardzo dobrze nadaje się do implementacji na GPU dzięki możliwości zrównoleglenia obliczeń. 3

7 1.2 Cele pracy Celem niniejszej pracy jest realizacja kompresji obrazów oraz sekwencji wideo przy użyciu metod falkowych. Szczególny nacisk został położony na porównanie zwykłej implementacji z implementacją bazującą na równoległych obliczeniach zrealizowanych na procesorze karty graficznej. Sprawdzona została również efektywność kompresji różnych algorytmów kwantyzacji i funkcji falkowych. Praca zawiera kompletny opis algorytmów wykorzystanych w poszczególnych krokach kompresji. Przedstawiłem też kilka przykładów pozwalających na zrozumienie działania poszczególnych metod. Umieściłem również krótki opis technologii NVIDIA CUDA. Dzięki temu praca może służyć jako materiał dydaktyczny dla osób chcących zapoznać się z zastosowaniem metod falkowych w kompresji, jak również z wykonywaniem obliczeń na GPU. 1.3 Zawartość pracy Rozdział drugi zawiera wstęp teoretyczny dotyczący transformaty falkowej. Przedstawiłem w nim algorytmy obliczenia transformaty wraz z przykładem. W rozdziale trzecim przedstawione są różne metody kwantyzacji skalarnej. Rozdział czwarty opisuje metodę kompresji bezstratnej jaką jest kodowanie arytmetyczne i zawiera przykład kodowania i dekodowania wybranego ciągu. Rozdział piąty jest w całości poświęcony technologii NVIDIA CUDA, skupiając się na elementach wykorzystanych w implementacji. W rozdziale szóstym znajduje się opis proponowanego rozwiązania, a w rozdziale siódmym opis implementacji. Rozdział ósmy przedstawia wyniki testów wykonanej aplikacji. Ostatni, dziewiąty rozdział zawiera podsumowanie całej pracy. 4

8 2 Transformata falkowa 2.1 Informacje ogólne Transformaty wykorzystywane w przetwarzaniu sygnałów wykorzystują iloczyn skalarny badanego sygnału przez część nazywaną jądrem przekształcenia. Wykonanie takiego działania na sygnale pozwala uzyskać jego reprezentację w nowej dziedzinie, która może być korzystniejsza dla jego reprezentacji bądź analizy. Transformata falkowa, podobnie jak transformata Fouriera należy do przekształceń całkowych. Podstawowy wzór opisujący transformatę falkową funkcji ciągłej x(t) ma postać: X(a, b) = 1 a ( ) t b x(t)ψ dt (1) a gdzie współczynnik a to czynnik skalujący, b to przesunięcie, ψ to sprzężenie zespolone falki bazowej nazywanej falką matką (mother wavelet). Wykorzystując współczynniki a i b jesteśmy w stanie wygenerować całą rodzinę falek umożliwiając reprezentację badanej funkcji na różnym poziomie szczegółowości. Do odtworzenia pierwotnego ciągłego sygnału wykorzystujemy transformatę odwrotną o postaci: x(t) = 0 gdzie ψ jest funkcją odwrotną do ψ. 2.2 Funkcja falkowa 1 a 2 X(a, b) 1 a ψ ( ) t b dbda (2) a W najbardziej znanej transformacie Fouriera jako jądro wykorzystywane są funkcje sinusoidalne. Transformata falkowa nie ma ściśle określonej funkcji jądra [1]. Może być nią dowolna funkcja spełniająca następujące warunki: 1. Jej wartość średnia ma mieć wartość 0 ψ(x)dx = 0 2. Musi mieć skończone pasmo przenoszenia, tj. poza określonym zakresem jej wartość jest równa 0 3. Musi mieć odpowiadającą funkcję skalującą ϕ(t) 5

9 2.3 Realizacja dyskretnej transformaty falkowej przy użyciu filtrów Na potrzeby cyfrowego przetwarzania sygnałów wykorzystywana jest dyskretna transformata falkowa (DWT - Discrete Wavelet Transform) [2] [10] [19]. Mnożenie we wzorach 1 i 2 przekłada się na obliczenie splotu ciągów, które w dziedzinie cyfrowego przetwarzania sygnałów wyrażane są przez operację filtracji. Aby efektywnie zaimplementować transformatę falkową należy najpierw wyznaczyć zestawy filtrów. Dzięki właściwościom funkcji falkowych możemy wygenerować całą rodzinę funkcji falkowych do reprezentacji sygnału na różnym poziomie szczegółowości. Dla danej funkcji falkowej należy wyliczyć współczynniki filtru górno i dolnoprzepustowego (oznaczane odpowiednio H 0 i H 1 ) oraz filtrów syntezy (F 0 i F 1 ). Sygnał poddawany jest filtracji i uzyskujemy na wyjściu filtra dolno przepustowego składowe niskoczęstotliwościowe (y L ), a na wyjściu filtru górno przepustowego składowe wysokoczęstotliwościowe (y H ). y L [n] = (x H 1 )[n] y H [n] = (x H 0 )[n] (3) W wyniku tego działania dostajemy jednak dwa wektory współczynników o długości równej wektorowi wejściowemu. Tą nadmiarowość redukujemy usuwając co drugą próbkę z tych wektorów (symbolicznie oznaczane jest to przez 2) i mnożąc przez 2. Sygnał poddany takiej filtracji podzielony jest na dwa pasma i aby wrócić do jego poprzedniej postaci należy najpierw przywrócić pierwotną ilość próbek. Wykonuje się to poprzez wstawienie zer w miejsca poprzednio usuniętych wartości (oznaczane przez 2). Jako że próbki nieusunięte zostały pomnożone przez 2 moc sygnału jest zachowana. Tak otrzymane wartości poddawane są filtracji odwrotnej przez bank filtrów F 0 i F 1 i sumowane. Rysunek 1: Bank filtrów analizy i syntezy Na rysunku 1 przedstawiony został bank filtrów realizujący dekompozycję, a następnie syntezę danego sygnału x. W pracach [1], [19] zostały szczegółowo podane wyprowadzenia 6

10 wzorów jakie mają spełniać zestawy filtrów H 0 H 1 F 0 F 1, aby sygnał po przejściu przez nie został identycznie zrekonstruowany. Mają one postać: H 0 (z)f 0 (z) + H 1 (z)f 1 (z) = 2 H 0 ( z)f 0 (z) + H 1 ( z)f 1 (z) = 0 Wyznaczając odpowiednie wartości współczynników filtrów jesteśmy w stanie efektywnie implementować algorytmy transformaty falkowej. Dekompozycja sygnału może być kontynuowana w podpaśmie najniżej częstotliwości. Na rysunku 2 przedstawiono trzypoziomowy schemat dekompozycji wraz z podziałem pasma częstotliwości. Obliczanie transformaty dla poziomu drugiego odbywa się w dolnym paśmie częstotliwości, który stanowi połowę długości wejściowego sygnału. Rysunek 2: Podział pasma częstotliwości w banku filtrów analizy Współczynniki transformaty falkowej z poszczególnych poziomów dekompozycji pokrywają całe spektrum częstotliwości. Nie tracimy więc żadnej informacji w wyniku wykonania tego przekształcenia. Współczynniki zwrócone przez filtr górnoprzepustowy nazywamy współczynnikami detali, a współczynniki zwrócone przez filtr dolnoprzepustowy współczynnikami uśrednionymi. 2.4 Przykład obliczenia transformaty i transformaty odwrotnej Obliczanie transformaty oraz transformaty odwrotnej zostanie przedstawione przy wykorzystaniu falki Haara. Transformacie zostanie poddany ośmioelementowy ciąg liczbowy. Wykonana zostanie trzypoziomowa dekompozycja sygnału wejściowego. Najpierw przedstawię postać falki Haara. 7

11 Falka Haara Falka Haara jest najstarszą i najprostszą funkcją falkową. Wartość średnia funkcji ψ(x) wynosi 0. Ma ona również ograniczony nośnik (poza określonym zakresem jej wartość jest równa 0) i posiada odpowiednią funkcję skalującą. Spełnione są więc wszystkie warunki stawiane funkcji falkowej. Podstawowy wzór opisujący falkę Haara ma postać: 1 dla 0 t < 1/2 ψ(x) = 1 dla 1 t < dla pozostałych t a funkcję skalującą ϕ(t): 0 dla 0 t < 1 ϕ(t) = 1 dla pozostałych t Rysunek 3: Falka Haara Obliczenie współczynników Załóżmy, że dany mamy ośmio elementowy ciąg: W pierwszym kroku obliczymy współczynniki uśrednione zmniejszając jednocześnie ich liczbę o dwa (operator 2). Dla ośmio elementowego ciągu potrzebować będziemy więc czterech współczynników uśrednionych. Obliczenie średniej wykonujemy parami. Pierwszy współczynnik ma wartość 3 ((4+2)/2), drugi 5 ((5+5)/2), itd. Współczynniki uśrednione wynoszą: 8

12 Współczynniki detali w dziedzinie Haara zawierają utraconą w wyniku uśrednienia informację. Pierwszy współczynnik ma wartość 1, ponieważ współczynnik uśredniony (3) jest o 1 mniejszy od współczynnika 4 i o 1 większy od współczynnika 2. Widzimy więc, że z jednego współczynnika uśrednionego i jednego detali jesteśmy w stanie zrekonstruować dwie wartości wejściowe. Nie tracimy zatem w wyniku tego przekształcenia żadnej informacji. Współczynniki detali wynoszą: Obliczanie transformaty będziemy kontynuować w dolnym podpaśmie częstotliwości, czyli na obliczonych współczynnikach detali. W poniższej tabeli znajdują się wyniki pełnej dekompozycji sygnału: Poziom Współczynniki uśrednione Współczynniki detali 1 [ ] [ ] 2 [4 4 ] [ 1 2] 3 [4] [0] W przedstawiony sposób obliczyliśmy współczynniki transformaty falkowej przy wykorzystaniu banku filtrów. Rekonstrukcja wejściowego ciągu polega na rekursywnym dodawaniu i odejmowaniu współczynników detali do współczynników uśrednionych na poszczególnych poziomach dekompozycji. Ostatecznie obliczone współczynniki mają wartości: Warto od razu zauważyć korzyść wynikającą z przejścia do bazy współczynników Haara. Energia sygnału kumuluje się w współczynnikach pasma dolnoprzepustowego, a współczynniki detali mają bardzo małą amplitudę i ich wartości są bliskie zeru. Wiele z tych współczynników można przybliżyć do zera wprowadzając jedynie niewielki błąd przy rekonstrukcji. Tak przedstawiony ciąg lepiej poddaje sie kompresji przy użyciu koderów entropijnych. 2.5 Współczynniki filtrów falkowych W przedstawionym wcześniej przykładzie użyłem najprostszej falki, czyli falki Haara. Do kompresji sygnałów wykorzystuje się zazwyczaj bardziej skomplikowane funkcje falkowe umożliwiające uzyskanie mniejszych zniekształceń po wykonaniu kwantyzacji współczynników. Filtry mają wówczas większą długość przez co zwiększa się koszt obliczenia pojedynczego współczynnika. 9

13 W mojej aplikacji wykorzystałem filtry ortogonalne Haar (haar) oraz Daubechies o długościach 4 i 6 (daub4 i daub6 ). Filtry ortogonalne Daubechies o różnych długościach konstruuje się według specjalnego wzoru przedstawionego m.in w pracy [4]. Filtr o długości 2 sprowadza się do filtru Haara. Filtry ortogonalne cechują się m.in. tym, że współczynniki banków analizy i syntezy są identyczne. Zaimplementowałem również filtry biortogonalne CDF97 (Cohen-Daubechies- Feauveau) oraz antonini (z pracy [10]). Filtry biortogonalne mają znaczenie lepsze cechy jeśli chodzi o kompresję. Filtr CDF97 jest wykorzystywany m.in. w standardzie JPEG2000. Filtry biortogonalne zapewniają rekonstrukcję sygnału. Banki filtrów analizy i syntezy nie mają jednak identycznych współczynników. W tabeli 1 znajdują się współczynniki banków filtrów dla falek ortogonalnych Haar, Daub4 i Daub6, natomiast w tabelach 2 i 3 współczynniki dla falki CDF97 i antonini. Ortogonalność zapewnia to, że do opisania falki wystarczą dwa zestawy współczynników. W przypadku falek biortogonalnych potrzeba czterech zestawów współczynników. Filtry falki CDF97 mają centrum w środkowym współczynniku (ma to znaczenie przy obliczaniu splotu z ciągiem wejściowym). Szczegółowy opis takich własności funkcji falkowych jak ortogonalność/biortogonalność, liczba momentów zanikających (vanishing moments), czy ostrość (sharpness) opisana jest w pracy [9]. Indeks współczynnika haar low haar high daub4 low daub4 high daub6 low daub6 high Tabela 1: Współczynniki filtrów falek ortogonalnych Haar, Daub4 i Daub6 Indeks współczynnika analysis low analysis high synthesis low synthesis high Tabela 2: Współczynniki filtrów falki biortogonalnej CDF97 10

14 Indeks współczynnika analysis low analysis high synthesis low synthesis high Tabela 3: Współczynniki filtrów falki biortogonalnej antonini 2.6 Transformata sygnałów wielowymiarowych Transformatę sygnału wielowymiarowego możemy uzyskać przez odpowiednie złożenie transformat jednowymiarowych. Dla kompresji szczególne znaczenie mają takie metody które koncentrują podobne współczynniki wokół siebie. W artykule [7] opisane zostały dwie podstawowe metody dekompozycji sygnału dwuwymiarowego (obraz), aby uzyskać jak najkorzystniejsze właściwości dla kompresji. Standard JPEG2000 wykorzystuje algorytm dekompozycji Mallata, który dzieli obraz na podpasma, w których znajdują się odpowiednio składowe niskoczęstotliwościowe (tło) i wysokoczęstotliwościowe (krawędzie). Na rysunku 4 przedstawiony jest sposób dekompozycji obrazu przedstawionego jako macierz X o wymiarach n x n. Rysunek 4: Dekompozycja obrazu przy użyciu algorytmu Mallata Na wejście banku filtrów na początku podawane są wektory wierszy i dokonywana jest na nich transformata jednowymiarowa. Następnie usuwamy co drugą kolumnę. W kolejnym kroku wykonujemy analogiczne działanie na wektorach kolumn. Wynik działania takiej procedury pokazany jest na rysunku 5. Dekompozycję można kontynuować w podpaśmie A, aby jeszcze zmniejszyć ilość współczynników pasma niskoczęstotliwościowego. 11

15 Rysunek 5: Schematyczny sposób działania dekompozycji wielorozdzielczej obrazu: a) obraz orginalny; b) obraz poddany dekompozycji jednopoziomowej c) przykład działania na obrazie Lena; W wyniku działania tego schematu w podpaśmie A uzyskujemy obraz w niższej skali, w podpaśmie B krawędzie pionowe, w C krawędzie poziome, a w D krawędzie ukośne. Kontynuując dekompozycję jesteśmy w stanie uzyskać silnie upakowaną reprezentację sygnału. Większość współczynników ma wartości zerowe bądź bardzo bliskie zeru. Po kroku kwantyzacji uzyskamy w pasmach wysokoczęstotliwościowych bardzo długie ciągi zer które skutecznie będą poddawały się kompresji bezstratnej. Transformata falkowa bardzo dobrze nadaje się do reprezentacji typowych obrazów, które składają się głównie z obszarów tła, czyli gradientów (składowe niskoczęstotliwościowe) oraz niewielkiej ilości obszarów reprezentujących krawędzie (składowe wysokoczęstotliwościowe). 2.7 Algorytm konwolucji Obliczenie transformaty oraz transformaty odwrotnej wymaga obliczenia wyjścia filtrów analizy i syntezy. Często stosowanym rozwiązaniem jest algorytm konwolucji. Dla ciągu x i filtru h wyjście y ma postać: y[n] = (x h)[n] = + k= = x[k]h[n k] (4) Przedstawione wcześniej wzory (3) na dyskretną transformatę przyjmują postać: y L [n] = (x H 1 )[n] = y H [n] = (x H 0 )[n] = + k= + k= = x[k]h 1 [2n k] = x[k]h 0 [2n k] (5) Zastosowano tutaj od razu operator 2 wyrzucania co drugiej próbki. 1 Takie zastosowanie algorytmu konwolucji doprowadza jednak do kilku problemów. Przede wszystkim 1 czynnik H[n k] został zamieniony na H[2n k] 12

16 w praktycznej realizacji dysponujemy sygnałami oraz filtrami o skończonej liczbie współczynników. Moglibyśmy oczywiście uznać, że poza zadanym zakresem wartości te są równe zero (zero padding). W wyniku tego działania uzyskamy jednak wyjście filtru o długości N +K 1 (N - długość sygnału wejściowego, K - liczba współczynników filtru). Usunięcie K 1 nadmiarowych współczynników uniemożliwiłoby prawidłową rekonstrukcję sygnału. Lepszym rozwiązaniem jest periodyczne rozszerzenie sygnału na granicach (periodic extension). Na rysunku 6 pokazany został schemat rozszerzenia periodycznego. Po wykonaniu filtracji na tak roszerzonym sygnale o okresie N, otrzymamy wyjście filtru o okresie N. Wiedząc, że rozszerzaliśmy sygnał periodycznie całą informację o wyjściu filtru możemy zapisać wykorzystując N współczynników. Periodyczne rozszerzanie sygnału x o długości N wyraża zależność: x[n] dla 0 n < N x[n] = x[ n] dla n < 0 x[n n] dla n N Rysunek 6: Rozszerzanie periodyczne oraz roszerzanie symetryczne Przedstawiony schemat rozszerzania sygnału ma jednak kilka wad, które rozwiązuje rozszerzanie symetryczne (symmetric extension). Rozszerzanie periodyczne jest ograniczone do sygnałów o długości podzielnej przez dwa. Tak więc dla transformaty falkowej o D poziomach dekompozycji, sygnał musi mieć długość będącą wielokrotnością liczby 2 D. Dodatkowo na granicy sygnału pojawia się nieciągłość, która powoduje większą wartość współczynników wysokich częstotliwości, co skutkuje większym kosztem kodowania entropijnego. Rozwiązanie tych problemów zapewnia rozszerzanie symetryczne (rysunek 6). Działa na sygnałach dowolnej wielkości i usuwa nieciągłość na granicach. Ogólnym celem jest uzyskanie symetrycznego sygnału wyjściowego. Schemat rozszerzania jest jednak bardziej skomplikowany i zależny od zastosowanych banków filtrów. Szczegółowy opis działania rozszerzania symetrycznego znajduje się w pracy [3]. 13

17 3 Metody kwantyzacji W wyniku obliczenia transformaty falkowej otrzymujemy współczynniki o wartościach ciągłych. Aby możliwe było ich skuteczne skompresowanie koderem bezstratnym należy najpierw je skwantyzować. Krok ten jest krokiem stratnym powodującym zniekształcenia zrekonstruowanego sygnału. Dobór odpowiedniego algorytmu kwantyzacji umożliwia znaczącą redukcję alfabetu występujących symboli. Najczęściej stosowaną miarą zniekształceń spowodowanych kwantyzacją jest miara błędu średniokwadratowego MSE (ang. Mean Square Error). Dla sygnału X o długości n wyraża się ona wyrażana wzorem: MSE = 1 (x(i) x (i)) 2 (6) n i Warto zauważyć że ta miara przy jej minimalizacji dąży do globalnego zmniejszenia błędu. Korzystne więc może być uzyskanie mniejszych błędów dla dużej liczby współczynników kosztem uzyskania znacznych błędów dla niewielkiej liczby współczynników. 3.1 Skalarna kwantyzacja równomierna Podstawowym schematem kwantyzacji jest kwantyzacja równomierna (ang. Uniform Quantization). Stosuje się ją dla sygnału o wartościach pomiędzy (f min, f max ). Cały zakres jest dzielony na L równych przedziałów o długości Q nazywanych przedziałem kwantyzacji (rysunek 7): Q = (f max f min )/L (7) Wartość leżąca w danym przedziale kwantyzacji jest odwzorowywana na środkową wartość tego przedziału. W wyniku kwantyzacji uzyskujemy indeks przedziału kwantyzacji: Q i (f) = f f min Q (8) Aby przeprowadzić dekwantyzację należy znać wartości f min i f max oraz indeksy przedziałów kwantyzacji dla poszczególnych symboli: Q(f) = Q i (f)q + Q/2 + f min (9) 3.2 Skalarna kwantyzacja nierównomierna Przedstawiona wcześniej metoda kwantyzacji jest optymalna jedynie dla sygnałów o rozkładzie równomiernym. Aby zminimalizować błąd średniokwadratowy (6), należy 14

18 Rysunek 7: Podział na przedziały kwantyzacji w kwantyzatorze równomiernym wykorzystać schemat, w którym przedziały kwantyzacji nie są równej wielkości. Tam gdzie występuje skupienie wartości należy zmniejszyć przedziały kwantyzacji (rysunek 8). Rysunek 8: Podział na przedziały kwantyzacji w kwantyzatorze nierównomiernym Nieliniowy charakter przekształcenia wymaga, aby przesłać informację o optymalnych przedziałach kwantyzacji do dekodera. Takie rozwiązanie zwiększa ilość potrzebnych bitów, więc nie jest stosowane w kompresji. Wykorzystywane są specjalne modele, które pozwalają na nieliniowe odwzorowanie przedziałów kwantyzacji bez wysłania dodatkowych informacji. 3.3 Skalarna kwantyzacja równomierna z rozszerzonym przedziałem zerowym Kwantyzacja równomierna z rozszerzonym przedziałem zerowym jest szczególnie efektywna przy kwantyzacji współczynników transformaty falkowej. W pasmach wysokich częstotliwości wiele współczynników ma wartości bardzo bliskie zeru. Dzięki niewielkiemu 15

19 rozszerzeniu przedziału zerowego przy niewielkim wzroście błędu średniokwadratowego znacząco zwiększamy ilość współczynników o wartości 0 (rysunek 9). Taki kwantyzator został opisany w części drugiej standartu JPEG2000 ([12]). Oznaczmy przez przedział kwantyzacji dla kwantyzatora równomiernego. Wówczas wartość skwantyzowana q dla elementu f wynosi: 0 dla f nz q = (10) sign(f) f +nz dla f nz W przedstawionym wzorze parametr nz odpowiada za szerokość przedziału zerowego i musi być przesłany do dekodera. Szerokość przedziału zerowego wynosi więc 2(1 nz). W standardzie JPEG2000 jako potencjalnie korzystną wartość wskazuje się nz 0.25 czyli 1.5 ([12]). Dekwantyzację wykonuje się wykorzystując wzór: 0 dla q = 0 f = (11) sign(q)( q nz + 0.5) dla q 0 Rysunek 9: Podział na przedziały kwantyzacji w kwantyzatorze równomiernym z rozszerzonym przedziałem zerowym 16

20 4 Kodowanie arytmetyczne Uzyskany w wyniku kwantyzacji strumień symboli kodowany jest koderem entropijnym. Metoda Huffmana wykorzystuje do zakodowania symbolu całkowitą liczbę bitów. Takie działanie powoduje jednak, że metoda ta jest nieoptymalna. Przytaczając zamieszczony w [11] przykład dla symbolu o prawdopodobieństwie 1/3 optymalna długość słowa kodowego wynosi około 1.6 bitów. Koder Huffmana musi jednak przypisać dla niego dwa bity przez co nie jest on optymalny. Różnica ta staje się jeszcze bardziej widoczna w przypadku kompresji obrazów, gdy jeden z symboli stanowi np. 90 procent wszystkich wystąpień. Wówczas optymalna długość słowa kodowego wynosi 0.15 bitów. Przypisując symbolowi jeden bit uzyskujemy ponad sześciokrotnie gorszy wynik niż wynosi optimum. 4.1 Kodowanie arytmetyczne oparte o arytmetykę rzeczywistoliczbową Kodowanie arytmetyczne to zupełnie inne podejście do kompresji ciągu symboli. Nie wykonujemy tutaj odwzorowania każdego symbolu na zakodowany ciąg bitów. Dla całego strumienia przyporządkowujemy jedną liczbę ułamkową nazywaną liczbą kodową. Wyznaczanie liczby kodowej odbywa się poprzez sukcesywne zacieśnianie przedziału kodowego wraz z kodowaniem kolejnych symboli. Ostatecznie liczbą kodową przekazywaną do dekodera jest dowolna liczba ułamkowa wybrana z przedziału kodowego po zakodowaniu wszystkich elementów. W dalszej części przedstawiony zostanie podstawowy algorytm kompresji i dekompresji kodera arytmetycznego opartego na liczbach rzeczywistych oraz prosty przykład. Algorytm kompresji: 1. Określenie prawdopodobieństwa występowania symboli. 2. Podzielenie przedziału [0, 1) na podprzedziały w zależności od częstości występowania symbolu. Kolejność w jakiej symbole są przypisywane do przedziałów nie ma znaczenia, ważne, aby była taka sama w koderze i dekoderze. Podprzedziały muszą pokrywać cały przedział początkowy i nie mogą na siebie zachodzić. 3. Czytanie symboli ze strumienia i zmiana przedziału kodowego. Po wczytaniu każdego z symboli wykonujemy aktualizację górnej (high) i dolnej (low) wartości przedziału kodowego korzystając z zależności: r an g e = h i g h low ; high = low + range high range ( symbol ) ; low = low + range low range ( symbol ) ; 17

21 gdzie funkcja high range zwraca górną granicę, a low range zwraca dolną granicę podprzedziału danego symbolu. 4. Wybranie liczby kodowej z pomiędzy otrzymanego przedziału. Dodatkowo aby możliwe było zdekodowanie ciągu do dekodera, musi być przekazana informacja o prawdopodobieństwach występowania symboli oraz o liczbie zakodowanych symboli. Algorytm dekompresji: 1. Pobranie informacji o prawdopodobieństwie występowania poszczególnych symboli oraz o liczbie symboli. Dodatkowo należy pobrać zakodowaną liczbę kodową. 2. Podzielenie przedziału [0, 1) analogicznie jak w punkcie 2 algorytmu kompresji. 3. Dekodowanie symbolu odbywa się poprzez określenie przedziału, w który wpada liczba kodowa. Po zdekodowaniu należy usunąć wpływ odczytanego symbolu na liczbę kodową korzystając z zależności: code number = ( code number low range ( symbol ) ) / ( high range ( symbol ) low range ( symbol ) ) ; 4. Jeśli nie odczytano wszystkich symboli powrót do punktu Przykład Załóżmy, że mamy do czynienia z czteroelementowym alfabetem a, b, c, d o prawdopodobieństwach występowania kolejno (0.5, 0.2, 0.2, 0.1 ). Po określeniu prawdopodobieństw dokonujemy podziału przedziału początkowego. Przyjmujemy leksykalną kolejność występowania symboli: symbol prawd. zakres a p < 0.5 b p < 0.7 c p < 0.9 d p < 1.0 Znając podział zakresu możemy przystąpić do kodowania ciągu symboli. W poniższej tabeli przedstawiono dolną i górna granicę przedziału kodowego po zakodowaniu poszczególnych symboli przykładowego ciągu wejściowego a, c, a, a, b, a, d, b. 18

22 symbol dolny przedział górny przedział a c a a b a d b Po zakodowaniu wybieramy liczbę kodową z końcowego zakresu [ , ). Przyjmijmy więc, że będzie to liczba Liczba ta wraz z informacją o prawdopodobieństwach symboli i ich liczbie jednoznacznie reprezentuje wejściowy ciąg. W poniższej tabeli przedstawiony został proces dekodowania. Po sprawdzeniu, w którym przedziale znajduje się liczba i wypisaniu symbolu na wyjście usuwany jest wpływ tego symbolu na liczbę kodową zgodnie z punktem trzecim algorytmu dekompresji. Liczba kodowa Symbol wyjściowy dolny przedział górny przedział a c a a b a d b STOP Podsumowując przedstawiony przykład należy zauważyć, że proces kodowania polega na sukcesywnym zawężaniu przedziału kodowego. W zależności od tego jakie prawdopodobieństwo ma kodowany symbol, przedział kodowy zawęża się w mniejszym bądź większym stopniu. Im szerszy uzyskamy przedział, tym mniej miejsc po przecinku zajmie na końcu liczba kodowa. 4.3 Kodowanie arytmetyczne oparte o arytmetykę całkowitoliczbową Przedstawiony wcześniej schemat kodowania arytmetycznego opierał się na arytmetyce rzeczywistoliczbowej. Nie da go się jednak zrealizować w praktycznych implementacjach 19

23 ze względu na ograniczoną długość rejestrów procesorów. Po zakodowaniu zaledwie kilkunastu symboli dochodziłoby do ich przepełnienia. Możliwe jest jednak zaimplementowanie kodera arytmetycznego przy wykorzystaniu arytmetyki całkowitoliczbowej wykorzystującej proste operacje bitowe na rejestrach. Bity reprezentujące liczbę kodową są wysuwane na wyjście w miarę kodowania kolejnych elementów. Dzięki temu możliwe jest w praktyce kodowanie dowolnie długich ciągów. Aby możliwe było reprezentowanie prawdopodobieństw w rejestrach całkowitoliczbowych, należy przyjąć że dolną granicę reprezentują wszystkie bity ustawione na zero, a górna granicę reprezentują wszystkie bity ustawione na jeden. Przez wszystkie bity rozumiane są tu wszystkie bity reprezentujące ułamek (implementacja używa 31 bitów z 32 bitowego rejestru). Warto również zauważyć, iż w obu liczbach część całkowita wynosi 0, więc można ją pominąć. Koder posiada zatem dwa rejestry dół i góra zainicjalizowane przez wartości 0000 i FFFF. Teraz w miarę kodowania kolejnych symboli wysuwane będą bity rejestru dół w momencie, gdy najbardziej znaczące bity obu rejestrów będą sobie równe. Zmiany będą zachodziły już tylko na mniej znaczących bitach, więc można bezpiecznie je wysunąć. Rejestr dół jest uzupełniany zerami natomiast rejestr góra jest uzupełniany jedynkami. Koder musi również zabezpieczyć się przed sytuacją, w której wysuwanie zostanie zatrzymane przez niedomiar. Kodowanie kolejnych symboli zacieśnia przedział kodowy, lecz różnica na najbardziej znaczących bitach może nie wystąpić od razu. Załóżmy, że posiadamy czterobitowe rejestry. Wartość rejestru dół wynosi 0110, a wartość rejestru góra wynosi Teraz w miarę procesu kodowania może dojść do sytuacji gdy po zakodowaniu kolejnego symbolu wartości te będą wynosić odpowiednio 0111 i W tym momencie najbardziej znaczące bity będą różne, uniemożliwiając wysunięcie. Rozwiązaniem tego problemu jest wcześniejsza detekcja możliwości wystąpienia tego problemu. Rozpatrując poprzedni przykład niedomiar występuje wtedy, gdy rejestr dół ma postać 01XX, a rejestr góra 10XX. Po wykryciu niedomiaru należy przesunąć w lewo wszystkie bity obu rejestrów oprócz najbardziej znaczących. Dekoder wczytuje sekwencyjne kolejne bity zakodowanej liczby kodowej do rejestru kod. Musimy również posiadać dwa rejestry dół i góra analogiczne do tych w koderze. W dekoderze trzeba wykonywać te same operacje na tych rejestrach jak w koderze, włączając wykrywanie niedomiaru. Po określeniu aktualnego prawdopodobieństwa dokonujemy odpowiednich przesunięć na wszystkich trzech rejestrach. Kompletny algorytm kodowania arytmetycznego w arytmetyce całkowitoliczbowej wraz w wyjaśnieniami można znaleźć w książkach [16] [11]. 20

24 4.4 Koder adaptacyjny Przedstawiony wcześniej algorytm kompresji posiada pewne wady. Pierwszą z nich jest konieczność wstępnego określenia prawdopodobieństwa występowania symboli. W takim przypadku algorytm musi być dwuprzebiegowy. Najpierw zliczana jest liczność poszczególnych symboli, a następnie wykonywane jest kodowanie. Tablica występowania symboli musi być dodatkowo przesłana do dekodera, zmniejszając efektywność kompresji. Warto zmniejszyć dynamikę elementów tablicy poprzez skalowanie, np. jeśli do zliczania liczności poszczególnych symboli wykorzystywaliśmy 32 bitowe liczby można je przeskalować i zapisać na 8 bitach. W ten sposób można w oszczędny sposób przesłać informację do dekodera o prawdopodobieństwach, nie wpływając znacząco na efektywność kompresji symboli. Lepszym rozwiązaniem jest zastąpienie statycznego modelu statystycznego modelem dynamicznym. Model ten jest aktualizowany w miarę kodowania kolejnych symboli, dopasowując się do charakterystyki kodowanych danych. Dekoder działa w analogiczny sposób. Po odkodowaniu danego symbolu, aktualizowane jest jego prawdopodobieństwo. Nie jest więc konieczne dwukrotne iterowanie przez dane. Dzięki temu nie trzeba również przesyłać informacji o prawdopodobieństwie występowania symboli. Zanim model dynamiczny dostosuje się do charakterystyki danych, kodowanie będzie mniej efektywne. Po zakodowaniu pewnej liczby symboli prawdopodobieństwa już się ustalą i kodowanie będzie efektywne. Dodatkowo model adaptacyjny dostosowuje się do charakterystyki lokalnej danych. Takie rozwiązanie pozwala uzyskać w większości przypadków lepszy stopień kompresji niż rozwiązanie z modelem statycznym. 21

25 5 Technologia NVIDIA CUDA W tym rozdziale zostały przedstawione podstawy technologii NVIDIA CUDA (Compute Unified Device Architecture). Szczególny nacisk został położony na elementy wykorzystane przy implementacji. Rozdział został przygotowany w oparciu o oficjalną dokumentację [14] oraz książkę [5]. Specyficzne konstrukcje kompilatora CUDA zostały wyjaśnione na prostych przykładach. 5.1 Efektywność obliczeniowa procesorów graficznych Jednostki obliczeniowe procesorów graficznych były rozwijane przez szereg lat, aby sprostać zapotrzebowaniu na renderowanie wysokiej jakości grafiki 3D. Przez ten czas wyewoluowały one w wysoce równoległe procesory posiadające znaczącą moc obliczeniową. Udostępniony przez firmę NVIDIA interfejs CUDA umożliwia wykorzystanie procesora graficznego do obliczeń nie związanych z renderowaniem grafiki. Procesory graficzne posiadają dużą liczbę prostszych rdzeni pozwalających na uzyskanie wysokiej efektywności obliczeń. Zwykłe jednostki obliczeniowe CPU zmniejszyły tempo wzrostu taktowania na rzecz wzrostu liczby rdzeni. Rysunek 10: Teoretyczna przepustowość obliczeń zmiennoprzecinkowych na liczbach pojedynczej precyzji [14] 22

26 Jako porównanie weźmy pod uwagę rodzinę procesorów Intel Core i7. Procesor ten posiada cztery rdzenie wspierające technologię hyperthreading, przez co może wykonywać równolegle osiem wątków. Procesor graficzny karty NVIDIA GeForceGTX 580 posiada 512 rdzeni pozwalając na równoczesne uruchomienie kilku tysięcy wątków. Osiąga on blisko 10 razy większą teoretyczną przepustowość obliczeń zmiennoprzecinkowych na liczbach pojedynczej precyzji (rysunek 10). Tak duża rozbieżność w wydajności bierze się z fundamentalnych różnic w architekturze obu rozwiązań (rysunek 11). Procesor CPU jest przystosowany do sekwencyjnego wykonywania instrukcji. Istnieją w nim mechanizmy, które sprawiają, że instrukcje wewnątrz procesora wykonywane są poza kolejnością mimo wrażenia sekwencyjnego wykonania (na rysunku blok CONTROL). Kolejną ważną cechą jest rozbudowany mechanizm dużej pamięci podręcznej zmniejszającej opóźnienia przy dostępnie do pamięci głównej. Procesor graficzny ze względu na swój uproszczony model pamięci ma kilkukrotnie większą przepustowość od głównej pamięci DRAM procesora. Renderowanie wysokiej jakości grafiki 3D wymaga wykonania ogromnych ilości obliczeń zmiennoprzecinkowych na każdą ramkę obrazu. Zajmuje się tym duża liczba wątków o uproszczonej logice wykonania. Mała pamięć podręczna pozwala zmniejszyć zużycie przepustowości pamięci DRAM, bez wprowadzania kosztownej logiki związanej z zarządzaniem nią, przeciwnie niż ma to miejsce w pamięci podręcznej procesora CPU. Rysunek 11: Architektury procesorów CPU i GPU [14] Procesor graficzny składa się z szeregu multiprocesorów strumieniowych (SM - streaming multiprocessor). Multiprocesory składają się grupy procesorów strumieniowych (SP - streaming processor), które mają wspólną pamięć podręczną. Ilości multiprocesorów i procesorów są zróżnicowane w zależności od danego procesora. Procesor graficzny działa na pamięci wewnętrznej karty graficznej. Pamięć karty graficznej będziemy nazywać pamięcią urządzenia (device memory), a zwykłą pamięć RAM pamięcią hosta (host memory). Szczegóły dotyczące architektury sprzętowej kart wspierających technologię CUDA 23

27 można znaleźć w książce [5]. W dalszej części przedstawię abstrakcje modelu programowania pozwalające na programowanie jednostki GPU bez znajomości sprzętowych szczegółów implementacyjnych. 5.2 Model programowania Z perspektywy programisty system składa się z hosta, który jest jest zwykłym procesorem, oraz z urządzeń (devices), które są wysoce wielowątkowymi procesorami graficznymi. Dzięki dużej liczbie jednostek obliczeniowych w procesorze graficznym, możliwe są równoczesne obliczenia na dużej ilości danych. W technologii CUDA kluczowe jest znalezienie tych fragmentów kodu, które wymagają intensywnych obliczeń arytmetycznych i można je zrównoleglić. Program wykorzystujący CUDA składa się z kodu wykonywanego na hoście oraz na urządzeniu. Do kompilacji kodu wykorzystywanego zarówno przez hosta jak i urządzenie wykorzystywany jest specjalny kompilator NVIDIA C (nvcc). Kod hosta to zwykły kod ANSI C i jest uruchamiany jak normalny proces. Kod urządzenia to ANSI C z pewnymi rozszerzeniami opisanymi w dalszej części rozdziału. 5.3 Funkcje kerneli Funkcje kerneli nazywane w skrócie kernelami (kernels), pozwalają na definiowanie kodu wykonywanego przez wątki w urządzeniu. Każdy z kerneli jest wykonywany równolegle przez osobne wątki, przeciwnie niż ma to miejsce w zwykłych funkcjach C. Aby zdefiniować kernel, należy przed deklaracją funkcji umieścić specyfikator global. Wywołanie kernela z odpowiednią liczbą wątków odbywa się poprzez wykorzystanie specjalnej składni <<<>>> (execution syntax). Całość musi być skompilowana kompilatorem nvcc. Poniżej znajduje się przykład kernela podnoszącego zadany ciąg liczb do kwadratu. Normalnie rozwiązanie takiego zadania opierałby się na sekwencyjnym obliczeniu kwadratu każdej liczby w pętli. Aby wykorzystać wielowątkowe możliwości procesora graficznego, każdy z elementów będzie obliczany oddzielnie. Indeks elementu w tablicy wyznaczany jest na podstawie unikalnego identyfikatora wątku (thread ID). Pobierany jest on z wbudowanej zmiennej threadidx. W wywołaniu kernela używamy specjalnej składni podając ilość wątków którą chcemy uruchomić. // d e f i n i c j a k e r n e l a g l o b a l void square ( float data ) { int index = threadidx. x ; data [ index ] = data [ index ] data [ index ] ; } int main ( ) {... 24

28 } // wywolanie k e r n e l a z N watkami // data d e v i c e memory square <<<1, N>>>(data ) ; 5.4 Hierarchia wątków Wątki mogą być indeksowane w trzech wymiarach x, y, z przy użyciu specjalnej zmiennej threadidx. Tworzą one wówczas odpowiednio jedno, dwu, lub trójwymiarowy blok wątków (thread block). Takie grupowanie pozwala w łatwy sposób wywoływać obliczenia na wektorach, macierzach i danych wolumetrycznych. Każdy z uruchomionych w ramach bloku wątków ma unikalne wartości indeksów x, y oraz z. Istnieje limit określający liczbę wątków w ramach bloku i obecnie wynosi on 512. Wątki danego bloku są przetwarzane na jednym multiprocesorze. Dzielą więc one zasoby ograniczonej pamięci podręcznej. Mają możliwość współpracy ze sobą poprzez wykorzystanie wspólnej pamięci podręcznej jak również synchronizację wykonania. Bloki są grupowane w jedno, bądź dwuwymiarowe kraty (grid). Maksymalny wymiar kraty zależy od urządzenia. Tak przygotowana krata wątków może liczyć od tysięcy do milionów prostych wątków. Schemat hierarchii wątków przedstawiony jest na rysunku 12. Rysunek 12: Schemat hierarchii wątków [5] 25

29 Poprawmy więc teraz wcześniejszy przykład tak, aby możliwe było wykorzystanie go dla tablicy dłuższych niż 512 elementów. Znając już pojęcie bloków, można wyjaśnić dokładnie, składnie wywołania kernela. Pierwszym argumentem jest liczba bloków, natomiast drugim jest ilość wątków na blok. Dla uproszczenia załóżmy, że długość tablicy jest wielokrotnością ilości wątków na blok: // i l o s c watkow na b l o k const int THREADS PER BLOCK = 512; } g l o b a l void square ( float data ) { int index = blockidx. x THREADS PER BLOCK + threadidx. x ; data [ i ] = data [ i ] data [ i ] ; int main ( ) {... // wywolanie k e r n e l a z N watkami int blocknum = N / THREADS PER BLOCK; square <<<blocknum, THREADS PER BLOCK>>>(data ) ; } Do uzyskania indeksu bloku w kracie użyliśmy specjalnej zmiennej blockidx. Jeśli chcemy wykorzystać kernel do przetwarzania macierzy bądź danych wolumetrycznych jako argumenty należy przekazać struktury dim3. Posiadają one trzy wartości x, y, z, którymi można określić wymiar bloku i kraty wątków. 5.5 Hierarchia pamięci Host i urządzenie mają oddzielne przestrzenie pamięci. Tak więc przed wykonaniem obliczeń należy zaalokować pamięć i przenieść dane z pamięci hosta do pamięci globalnej urządzenia (global memory). Po wywołaniu kernela pobieramy z powrotem wyniki do pamięci hosta i zwalniamy zaalokowaną pamięć urządzenia. Poniżej znajduje się uzupełniona o alokację i przesyłanie pamięci procedura main. Do alokacji pamięci na urządzeniu wykorzystywana jest funkcja cudamalloc, działająca analogicznie do funkcji z standardowej biblioteki C. Analogicznie działa również funkcja zwalniająca pamięć, cudafree. Funkcja cudamemcpy zajmuje się kopiowaniem pamięci do i z urządzenia. To, w którą stronę zachodzi przesyłanie danych, zależy od czwartego argumentu wywołania będącego enumeracją cudamemcpykind. int main ( ) { float hostmemory ; 26

30 ... float devicememory ; cudamalloc ( ( void ) devicememory, N s i z e ( float ) ) ; cudamemcpy( devicememory, hostmemory, N s i z e ( float ), cudamemcpyhosttodevice ) ;... square <<<blocknum, THREADS PER BLOCK>>>(deviceMemory ) ; } cudamemcpy( hostmemory, devicememory, N s i z e ( float ), cudamemcpydevicetohost ) ; cudafree ( devicememory ) ; Po przesłaniu danych do pamięci urządzenia, wątki pobierają swoją porcję danych z pamięci globalnej przy użyciu zmiennych threadidx oraz blockidx. Takie rozwiązanie nie wykorzystuje jednak pełnej wydajności procesora graficznego. Wątek ma dostęp do kilku innych rodzajów pamięci, które można wykorzystać dla uzyskania większej szybkości wykonania. Rysunek 13 pokazuje wszystkie rodzaje pamięci i ich związek z hierarchią wątków. Host przy użyciu funkcji cudamemcpy ma możliwość zapisu do pamięci globalnej (global memory) oraz do pamięci stałych (constant memory). Pamięć globalna została już przedstawiona na przykładach i służy do przekazywania danych i wyników obliczeń. Wątki mogą ją odczytywać i zapisywać. Pamięć stałych zapewnia krótszy czas dostępu i wysoką przepustowość przy założeniu tylko odczytu przez wątki. Ma ona również ograniczoną wielkość (64KB). Każdy z wątków posiada swoją pamięć lokalną oraz rejestry. Pamięć tego typu znajduje się bezpośrednio na procesorze. Jest ona dostępna jedynie dla tego wątku i zapewnia najlepszą wydajność. Wykorzystuje się ją do przechowywania często używanych zmiennych prywatnych dla danego wątku. Wątki będące w jednym bloku mają dostęp do wspólnej pamięci współdzielonej (shared memory). Ma ona znacznie krótszy czas dostępu niż pamięć główna i ograniczoną wielkość (16KB lub 48KB na multiprocesor). Można ją sobie wyobrazić jako ręcznie zarządzaną pamięć podręczną w ramach bloku. Wykorzystuje się ją zwłaszcza w przypadku dostępu do tych samych danych wejściowych przez wiele wątków, bądź dostępu do obliczeń pośrednich. Przedstawione rodzaje pamięci mają swój czas życia. Pamięć globalna i stałych jest dostępna przez czas działania aplikacji. Pamięci lokalne wątków oraz pamięć współdzielona ma czas życia równy czasowi życia bloku. Po wykonaniu bloku, pamięć jest zwalniana umożliwiając uruchomienie kolejnych bloków wątków. 27

31 Rysunek 13: Schemat hierarchii pamięci w procesorze graficznym [5] Do określenia pewnych typów pamięci, API określa odpowiednie specyfikatory: pamięć współdzielona - shared pamięć globalna - pamięć stałych - device constant Wykorzystanie pamięci współdzielonej, stałych i lokalnej pozwala ograniczyć użycie przepustowości pamięci globalnej, która jest wąskim gardłem w aplikacji wykorzystujących CUDA. Należy mieć jednak na uwadze, że wymienione rodzaje pamięci mają swoje limity. Przy zwiększaniu ich wykorzystania, możemy doprowadzić do zmniejszenia ilości wątków wykonywanych na danym multiprocesorze. 28

32 6 Opis proponowanego rozwiązania W tym rozdziale przedstawiony jest opis stworzonego przeze mnie narzędzia do kompresji sekwencji wideo i obrazów. Zaimplementowałem kompresor działający na procesorze CPU oraz na karcie graficznej wykorzystującej CUDA. Na początku przedstawię wymagania postawione aplikacji. Następnie opiszę funkcje udostępnione przez kompresor. Na końcu opiszę architekturę rozwiązania z wyszczególnieniem tych fragmentów aplikacji, które udało się zaimplementować przy użyciu procesora karty graficznej. 6.1 Wymagania dotyczące aplikacji Głównym celem zaprojektowanej aplikacji jest stworzenie narzędzia do kompresji sekwencji wideo przy wykorzystaniu metod falkowych i technologii NVIDIA CUDA. Aby możliwe było łatwe porównanie skuteczności kompresji z innymi rozwiązaniami, stworzony przeze mnie kompresor rozszerzyłem o możliwość kompresji obrazów. 2 Aplikacja musi umożliwiać kompresję w dwóch trybach, tj. przy wykorzystaniu CPU oraz przy wykorzystaniu CPU i procesora graficznego. W program powinny być wbudowane mechanizmy liczące czas wykonania poszczególnych jego części. Posiadając te dane można określić efektywność implementacji CUDA w stosunku do implementacji CPU, co jest głównym celem pracy. Kompresor powinien umożliwiać odczyt i zapis szeroko wykorzystywanych formatów plików. Zakodowane pliki w własnym formacie muszą posiadać wszelkie dane niezbędne do ich poprawnego odkodowania bez względu na wybrane parametry kodera. Ważne jest również poprawne dekodowanie plików zakodowanych na różnych platformach sprzętowych. 6.2 Funkcje aplikacji Interfejs Aplikacja udostępnia swoje funkcje poprzez argumenty wywołania. Komunikacja zwrotna odbywa się poprzez komunikaty. W argumentach wywołania możliwe jest określenie stopnia szczegółowości wyświetlanych informacji. W przypadku wystąpienia błędu jest wyświetlony odpowiedni komunikat oraz zwrócony kod błędu. Kompresja obrazów Aplikacja umożliwia kompresję obrazów bitmapowych. Możliwa jest kompresja obrazów w odcieniach szarości lub kolorowych. Obsługiwane formaty odczytu i zapisu plików bitmapowych to: pgm, bmp, jpg, tiff. Ze względu na zastosowany algorytm 2 W większości prac z dziedziny kompresji stratnej można, np. znaleźć wyniki dla standardowego obrazu testowego Lena. 29

33 obliczania transformaty falkowej, obraz musi mieć wymiary będące wielokrotnością liczby 2 d, gdzie d to liczba poziomów dekompozycji. Kompresja sekwencji wideo Aplikacja umożliwia kompresję sekwencji wideo. Wymagania dotyczące liczby kolorów oraz wymiarów są takie same jak dla kompresji obrazów. Obsługiwany wejściowy i wyjściowy format pliku to avi w formacie RAW i420 bez dźwięku. Wybór sposobu wykonania obliczeń Domyślnie aplikacja działa przy użyciu implementacji CPU. Możliwe jest jednak określenie by program zastosował implementację wykorzystującą procesor karty graficznej. Wyświetlanie czasu wykonania poszczególnych części programu W aplikację wbudowane są mechanizmy liczące czas wykonania poszczególnych kroków algorytmu kompresji i dekompresji. Określenie stopnia kompresji Aplikacja przy kompresji pobiera parametr określający żądany stopień kompresji. Dla przykładu chcąc uzyskać stopień kompresji 4:1 musimy podać wartość 4. Aplikacja nie obsługuje parametryzacji poprzez żądaną jakość obrazu zrekonstruowanego. Określenie innych parametrów Przekazując odpowiednie argumenty wywołania aplikacja przy kodowaniu pozwala na wybór algorytmów wykorzystywanych w poszczególnych krokach kompresji. Informacje te są zapisywane w zakodowanym pliku na potrzeby dekodera. Parametryzowane są następujące opcje: wykorzystana funkcja falkowa (dostępne filtry: Haar, Daub4, Daub6, CDF97 oraz Antonini), liczba poziomów dekompozycji transformaty falkowej, typ kwantyzatora (dostępny: kwantyzator równomierny, kwantyzator równomierny z rozszerzonym przedziałem zerowym) 30

34 6.3 Architektura rozwiązania Zaimplementowany przeze mnie kompresor opiera się na standardowym schemacie transformacyjnej kompresji stratnej. Na rysunku 14 znajduje się schemat kompresji obrazów. Kompresja sekwencji wideo przechodzi przez dokładnie te same kroki z pewnymi drobnymi różnicami. Rysunek 14: Schemat kompresji obrazów Formatowanie danych Pierwszym krokiem algorytmu kompresji jest formatowanie danych. Zadany obraz oryginalny musi być odpowiednio przechowywany, aby wykonanie na karcie graficznej było efektywne. Ważne jest, aby kanały kolorowego obrazu były przetwarzane oddzielnie. Wynika to z faktu, że transformata i transformata odwrotna musi być wykonana oddzielnie dla każdego kanału. Procesor karty graficznej przy pobieraniu danych z pamięci globalnej pobiera je od razu w większych blokach 32, 64 lub 128 bitowych. Technika ta nazywa się memory coalescing i ma na celu zmniejszenie liczby żądań do pamięci globalnej. Rysunek 15: Zmiana struktury przechowywania pikseli w pamięci Zakładając, że każdy z wątków oblicza jeden współczynnik transformaty, musiałby by on sięgać po co trzeci element. Miałoby to oczywiście zły wpływ na wydajność ze względu na zbędne pobranie niewykorzystywanych w obliczeniach wartości. Rysunek 15 przedstawia niezbędne w tym kroku ustawienie danych. Oddzielne przetwarzanie kanałów pozwala również zmniejszyć zużycie pamięci globalnej karty graficznej. W danej chwili wykonywane są obliczenia dla tylko jednego kanału. 31

35 Rysunek 16: Sekwencja obrazów przy przetwarzaniu jest grupowana (w - szerokość; h - wysokość; f - ilość ramek tworzących grupę) Wejściowym formatem dla sekwencji wideo jest sekwencja obrazów. Podział kanałów barw jest analogiczny do zastosowanego przy formatowaniu obrazów. Kompresor w danej chwili pracuje na określonej liczbie ramek (na rysunku 16 parametr f). Transformata falkowa dla sekwencji wideo odbywa się po trzech wymiarach, tak więc konieczne jest zastosowanie odpowiednio dużej liczby ramek, aby możliwe było wykonanie kilkupoziomowej dekompozycji sygnału. Po wykonaniu pozostałych kroków algorytmu na grupie ramek i zapisie zakodowanych danych do strumienia wyjściowego przetwarzanie odbywa się na kolejnej grupie ramek. Transformata kolorów Dla obrazów barwnych wykonywana jest transformata kolorów. Jej głównym celem jest wykorzystanie psychowizualnych cech ludzkiego zmysłu wzroku. Jak powszechnie wiadomo ludzki wzrok jest bardziej czuły na zmiany luminancji niż chrominancji. Powszechnie wykorzystywany model RGB przechowuje jasności w każdej z swoich składowych. Dla celów kompresji korzystniejsze są modele gdzie jasność jest przechowywana na jednej składowej, a barwy na dwóch pozostałych. W zaimplementowanym kompresorze wykorzystałem przejście do modelu Y C b C r, gdzie Y to jasność, a C b i C r to składowe opisujące barwę. Poniżej znajdują się wykorzystane wzory transformacyjne. Y R C b = G C r B 32

36 R Y G = (C b 128) B (C r 128) Algorytm obliczania transformaty kolorów łatwo daje się zrównoleglić i zaimplementować na GPU. Każdy z wątków ma dostęp do składowych RGB piksela. Na podstawie blockidx i threadidx może określić swój indeks. Następnie wykorzystując przedstawione wzory, dokonuje obliczenia wartości Y C b C r i zapisuje je na miejsce wartości RGB. Przy tak prostym dostępie do pamięci nie należy korzystać z pamięci współdzielonej. Każdy wątek korzysta jedynie ze swoich danych. Transformata falkowa Po opcjonalnym wykonaniu transformacji kolorów wykonywana jest transformata falkowa. We wstępie teoretycznym przedstawiona została metoda obliczania współczynników transformaty falkowej, przy użyciu algorytmu konwolucji z periodycznym rozszerzaniem sygnału na granicach. Taki właśnie algorytm został zaimplementowany zarówno na procesorze CPU i GPU. Kompresor pozwala na użycie kilku zdefiniowanych funkcji falkowych. Każda falka składa się z zestawu czterech filtrów. Są to pary nisko i wysokoczęstotliwościowych filtrów analizy i syntezy. Każdy z filtrów posiada ciąg współczynników o danej długości i parametr określający pierwszy współczynnik filtru. Mówi on o ile pozycji w lewo należy przesunąć filtr przy obliczaniu splotu (rysunek 17). Rysunek 17: Konwolucja obrazu dla filtru o czterech współczynnikach bez przesunięcia i z przesunięciem równym jeden Obliczenie splotu wejściowego ciągu x z filtrem h, można zaimplementować przy użyciu dwóch prostych pętli zagnieżdżonych. Obliczenie wykonujemy tylko dla co drugiego elementu ze względu na wyrzucenie w kolejnym kroku co drugiej próbki. Ważne jest periodyczne rozszerzenie sygnału na granicach. W przypadku implementacji na GPU każdy z wątków wykonuje obliczenie jednego współczynnika dla niskich częstotliwości i jednego dla wysokich. Jeśli oba filtry analizy 33

37 mają podobną długość i przesunięcie, wówczas wykorzystują one te same elementy wejściowe do obliczenia obu współczynników (rysunek 18). Wykonując więc obliczenie obu współczynników, zmniejszamy zużycie przepustowości pamięci. Dodatkowo warto wykorzystać pamięć współdzieloną ze względu na dostęp do tych samych współczynników przez kilka wątków. Rysunek 18: Równoczesne obliczenie współczynników nisko i wysokoczęstotliwościowych Obliczanie transformaty dla sygnałów wielowymiarowych wykonujemy dla każdego wymiaru oddzielnie korzystając z separowalności funkcji falkowej. W zaprojektowanym przeze mnie kompresorze ramki sekwencji wideo grupuję w bloki tworząc trójwymiarową macierz pikseli (rysunek 19). Tak uzyskaną macierz pikseli poddaję transformacie falkowej po każdym z wymiarów. Sposób dekompozycji dla obrazów został już przedstawiony w wstępnie teoretycznym. Rysunek 19: Trójwymiarowa macierz pikseli 34

38 W wyniku obliczenia transformaty uzyskamy trójwymiarowe podmacierze, w których znajdą się współczynniki poszczególnych podpasm. Tak uzyskane dane są sprowadzane do postaci liniowej. Na rysunku 20 przedstawiony został sposób linearyzacji dla obrazu. Dane w każdym podpaśmie są kopiowane wiersz po wierszu. Poszczególne podpasma są ustawione od pasma najniższych częstotliwości do najwyższych. Dla obliczonej trójwymiarowej macierzy współczynników dane w podmacierzy są kopiowane ramka po ramce, a w ramach ramki, wiersz po wierszu. Wykonanie linearyzacji ułatwia w kolejnych krokach dostęp do współczynników. Dane są tam przetwarzane w ramach podpasm, nie jest więc konieczne złożone indeksowanie. Wystarczy znać wskaźnik do pierwszego elementu podpasma i długość podpasma. Rysunek 20: Sposób linearyzacji obrazu poddanego transformacie Kwantyzacja Po wykonaniu transformaty uzyskujemy zbiór podpasm współczynników o wartościach ciągłych. Aby w kolejnym kroku możliwe było zakodowanie ich koderem arytmetycznym, należy je zdyskretyzować. W tym kroku odpowiednio dobierając liczbę poziomów dekompozycji zmniejszamy jego dynamikę w taki sposób, aby skutecznie poddawał się kompresji koderem arytmetycznym. Wybór liczby poziomów dekompozycji realizuje algorytm optymalizacji R-D (rate-distortion). Każde z podpasm jest kwantyzowane przy użyciu innej liczby poziomów dekompozycji. Wynika to oczywiście z znaczących różnic w dynamice poszczególnych podpasm. W pasmach wysokiej częstotliwości amplituda współczynników jest niewielka w porównaniu z pasmami niskich częstotliwości, gdzie kumuluje się energia sygnału. Liczba poziomów kwantyzacji jest równa 2 b, gdzie b to ilość bitów przeznaczonych na dany współczynnik. W wykonanym koderze zaimplementowałem dwa kwantyzatory: kwantyzator równomierny i kwantyzator równomierny z rozszerzonym przedziałem zerowym. W przypadku kwantyzatora z rozszerzonym przedziałem zerowym sygnał jest uznawany za symetryczny. 35

39 Oznacza to, że jego amplituda nie wyraża się poprzez różnicę między największym i najmniejszym współczynnikiem, a poprzez dwukrotność wartości bezwzględnej z maksimum wartości bezwzględnej tych wartości (2 max( max, min )). Algorytm kwantyzacji nie został zaimplementowany na GPU ze względów wyjaśnionych w dalszej części pracy. Kodowanie arytmetyczne Po wykonaniu kwantyzacji uzyskujemy w każdym z podpasm całkowite współczynniki mieszczące się na b bitach. W zaprojektowanym kompresorze krok kodowania bezstratnego realizuje adaptacyjny koder arytmetyczny. Model statystyczny jest inicjalizowany równomiernie, tj. każdy symbol uzyskuje to samo prawdopodobieństwo. Wraz z kodowaniem kolejnych symboli model dostosowuje się do charakterystyki danych. Zdecydowałem się na wykorzystanie nowego modelu dla każdego z podpasm. Do wyjaśnienia tej decyzji przedstawię przykład. W wyniku optymalizacji R-D pasmo najniższych częstotliwości zostało skwantyzowane przy użyciu 8 bitów, a pasmo najwyższych częstotliwości przy użyciu 3 bitów. Tak jak zostało wspomniane wcześniej w pasmach wysokich częstotliwości większość współczynników przyjmuje wartości 0. Wykorzystując jeden i ten sam model, kodowanie pasma wysokich częstotliwości byłoby nieefektywne ze względu na to, że model przystosowałby się do pasma niższych częstotliwości. Oczywiście po pewnym czasie przystosowałby się on do charakterystyki danych, ale trwałoby to dłużej niż w przypadku rozpoczęcia kodowania od prawdopodobieństw wynoszących 1/8. Dodatkowo zaadoptowany przeze mnie algorytm optymalizacji R-D uniemożliwiał wykorzystanie tego samego modelu. Sekwencyjny charakter algorytmu kodowania arytmetycznego polegający na przesunięciach bitowych na trzech rejestrach dyskwalifikuje go przy implementacji na procesorze karty graficznej. Uzyskany w wyniku działania algorytmu strumień bitów jest zapisywany do pliku. Jest on poprzedzony odpowiednim nagłówkiem oraz danymi każdego z kwantyzatorów. Optymalizacja R-D W przedstawionym do tej pory schemacie kompresji brakuje informacji o sposobie wyboru liczby poziomów dekompozycji. Kompresor posiada parametr określający żądany poziom kompresji, np. 4 : 1. Żeby uzyskać taki poziom kompresji, należy tak dobrać liczbę poziomów kwantyzacji poszczególnych podpasm, aby po zakodowaniu skwantyzowanych współczynników koderem arytmetycznym osiągnąć żądaną liczbę bitów. Dobraniem liczby poziomów dekompozycji zajmują się algorytmy optymalizacji R-D (rate distorion). Na rysunku 21 przedstawiona jest przykładowa krzywa R-D dla jednego z kwantyzatorów. Wraz z zmniejszaniem kosztu bitowego (rate), zwiększają się zniekształcenia (distortion). Gdyby był wykorzystywany tylko jeden kwantyzator, wystarczyłoby zaczynając od pewnej ustalonej liczby bitów na symbol sprawdzać, czy mieścimy się założonym budżecie bitów. Jeśli nie, to należałoby zmniejszyć liczbę bitów na symbol, co 36

40 spowodowałoby większe zniekształcenia kwantyzacyjne i równocześnie zmniejszenie liczby potrzebnych bitów. Rysunek 21: Krzywa R-D dla jednego kwantyzatora Ze względu na to, iż koder wykorzystuje wiele kwantyzatorów, problem staje się trudniejszy. Ważne staje się takie dobranie liczby poziomów kwantyzacji w poszczególnych pasmach, aby globalne zniekształcenia były minimalne przy spełnieniu ograniczenia na liczbę wykorzystanych bitów. Silna kwantyzacja w pasmach wysokich częstotliwości pozwala uzyskać niski koszt bitowy przy niewielkich zniekształceniach. Na potrzeby mojego kodera zaadaptowałem algorytm R-D z biblioteki Wavelet Image Compression Construction Kit, 3 który opiera się na artykule [20]. Korzysta on z powszechnie wykorzystywanej metody mnożników Lagrange a. Problem minimalizacji można przedstawić jako minimalizację funkcji D + λr, gdzie λ jest mnożnikiem Lagrange a. Na rysunku 21 zmienna λ określa nachylenie stycznej do krzywej R-D. Optymalizacja przy użyciu mnożników Lagrange a polega na zmianie parametru λ aż do uzyskania żądanego kosztu bitowego. Szczegóły dotyczące algorytmu opisane są w wspomnianej pracy. Wykorzystana metoda optymalizacji wymaga, aby dla każdego z podpasm przygotować krzywe R-D. Miarą zniekształceń D jest przedstawiony wcześniej błąd średniokwadratowy. Aby uzyskać możliwie precyzyjnie żądaną liczbę bitów, zdecydowałem się na obliczanie kosztu bitowego poprzez kodowanie uzyskanych w wyniku kwantyzacji współczynników. Koder arytmetyczny działa wtedy w trybie zliczania bajtów i nie jest wówczas zapisywany strumień wyjściowy. Konieczność wielokrotnego kodowania koderem arytmetycznym skwantyzowanych współczynników uniemożliwiła zaimplementowanie kroku kwantyzacji na GPU. Wynika to z wysokiego kosztu przesyłania danych z pamięci urządzenia do pamięci głównej

41 Dekompresja Skompresowany plik zawiera w sobie nagłówek określający wszystkie niezbędne do wykonania dekompresji dane. Są to między innymi wymiary, liczba kanałów, liczba poziomów dekompozycji, zastosowana funkcja falkowa, kwantyzator oraz koder arytmetyczny. Dodatkowo przed zakodowanymi współczynnikami znajdują się dane wykorzystywane przez kwantyzatory w procesie dekwantyzacji. Są to wartość minimalna, maksymalna współczynników oraz liczba poziomów kwantyzacji. Po odczytaniu nagłówka następuje zdekodowanie danych zakodowanych koderem arytmetycznym. Ważne jest śledzenie liczby odczytanych elementów, aby przełączyć model statystyczny kodera przy odczycie kolejnego podpasma. Po odczytaniu każdego elementu jest on od razu poddawany dekwantyzacji. Dzięki temu nie jest konieczne wykorzystanie pośredniego bufora dla skwantyzowanych wartości. Przed wykonaniem transformaty odwrotnej należy zdelinearyzować współczynniki falkowe do pierwotnej postaci. Następnie współczynniki falkowe są poddawane odwrotnej transformacie falkowej, która jest wykonywana analogicznie do zwykłej transformaty. Jedyną różnicą jest wykorzystanie par filtrów syntezy zamiast filtrów analizy i wstawienie dodatkowych zer pomiędzy współczynnikami. Jeśli obraz bądź sekwencja wideo była poddana transformacie kolorów, należy wykonać odwrotną transformatę kolorów. Po jej wykonaniu uzyskujemy już pełną rekonstrukcję w pamięci. Ostatnim krokiem jest reorganizacja danych, mająca na celu ustalenie takiego formatu danych, aby możliwy był zapis w innej postaci (np. jeśli wartości poszczególnych barw piksela muszą być obok siebie). Kroki, które musi wykonać dekoder, są przedstawione na rysunku 22. Rysunek 22: Schemat dekompresji obrazów 38

42 7 Implementacja projektu W tym rozdziale przedstawiony jest opis implementacji projektu. Najpierw opiszę wykorzystywaną platformę sprzętową, niezbędne narzędzia oraz biblioteki. Następnie przedstawię w szczegółach zaimplementowany algorytm obliczania transformaty falkowej na procesorze GPU. Na końcu opiszę wbudowane w aplikację mechanizmy mierzenia czasu wykonania. 7.1 Platforma sprzętowa Ze względu na konieczność porównania implementacji CPU i GPU ważne jest na jakim sprzęcie została ona przetestowana. Na potrzeby implementacji i testów wykorzystano następującą konfigurację sprzętową: CPU AMD Atholon II X3 440 (3x3GHz) Chipset AMD 785 RAM DDR3 2x2GB (1333Mhz) GPU NVIDIA GeForce GTS250 1GB W poniższej tabeli zamieszczam właściwości wykorzystanego akceleratora graficznego pod kątem technologii NVIDIA CUDA: Compute capability * 1.1 Liczba multiprocesorów (MP) 16 Liczba rdzeni w multiprocesorze (SP) 8 Łączna liczba rdzeni 128 Taktowanie zegara 1.46GHz Łączna ilość pamięci globalnej bajtów Ilość pamięci współdzielonej na rdzeń bajtów Liczba rejestrów na rdzeń 8192 Maksymalna liczba wątków na blok 512 Maksymalna wielkość każdego z wymiarów w bloku 512 x 512 x 64 Maksymalna wielkość każdego z wymiarów w kracie x x 1 * Compute capability określa możliwości obliczeniowe procesora graficznego. Główny numer rewizji mówi o architekturze procesora, natomiast numer podrewizji określa stopniowo rozwijane rozszerzenia w ramach tej samej architektury. Szczegóły można znaleźć w dodatku G dokumentacji [14]. Komputer pracował pod kontrolą systemu Ubuntu Linux bit z jądrem w wersji Wersja sterowników NVIDIA to

43 7.2 Narzędzia i biblioteki Do implementacji projektu wykorzystałem następujące narzędzia: Cuda Toolkit v4.0 Zawiera zbiór niezbędnych narzędzi (np. kompilator nvcc) i bibliotek. Dołączona jest tu również dokumentacja i przykładowe aplikacje wraz z kodem źródłowym. Scons Narzędzie służące do budowania aplikacji, zastępujące makefile. Dzięki temu, że jest napisane w języku Python bardzo łatwo zwiększa się jego funkcjonalność. Wykorzystałem rozszerzenia pozwalające na kompilację kodu CUDA i automatyczne uruchamianie testów jednostkowych po każdym zbudowaniu aplikacji. valgrind Narzędzie umożliwiające detekcję wycieków pamięci i nieprawidłowych odwołań do pamięci. QtCreator Środowisko programistyczne dla języka C++. Szczególnie przydatną funkcją jest dobrze działający graficzny debugger bazujący na gdb. svn Użyłem systemu kontroli wersji svn. Kod projektu znajduje się w publicznie dostępnym repozytorium pod adresem: wavelet-compressor/. Poniżej znajdują się użyte biblioteki oraz zaadaptowany kod wraz z opisem ich wykorzystania w zaimplementowanym projekcie: OpenCV Biblioteka OpenCV (Open Source Computer Vision) została wykorzystana do odczytu i zapisu różnych formatów plików obrazów i sekwencji wideo. googletest Biblioteka do tworzenia testów jednostkowych w C++. Wavelet Image Compression Construction Kit Szkielet aplikacji kompresującej obrazy przy wykorzystaniu transformaty falkowej. Zaadaptowałem stąd kod algorytmu optymalizacji R-D. Koder arytmetyczny z publikacji [6] Wykorzystałem kod kodera arytmetycznego opisanego w wyżej wymienionej pracy. Wprowadzone zostały zmiany umożliwiające zmianę modelu i kodowanie/dekodowanie pojedynczych symboli. 40

44 7.3 Algorytm obliczania transformaty falkowej na procesorze GPU W rozdziale poświęconym opisowi proponowanego rozwiązania przedstawione zostały główne założenia dotyczące implementacji transformaty falkowej na procesorze karty graficznej. Każdy z wątków będzie zajmował się równocześnie obliczaniem jednego współczynnika wysokich częstotliwości i jednego niskich. Tak więc dla jednowymiarowego sygnału o długości N będziemy potrzebowali N/2 wątków. Dodatkowo dla filtrów o większej długości kilka wątków będzie korzystało z tych samych współczynników (rysunek 23). Rysunek 23: Dostęp do tych samych elementów przy obliczaniu konwolucji z filtrem o ośmiu współczynnikach Dzięki takiemu dostępowi do pamięci warto jest wykorzystać pamięć współdzieloną. Wątki ładują dane do pamięci współdzielonej, a następnie obliczają transformatę korzystając z zgromadzonych tam danych. Jako że każdy z wątków oblicza dwa współczynniki, musi on również załadować dwa współczynniki. Nie można również zapomnieć o tym, że do obliczenia konwolucji potrzebujemy kilku sąsiednich elementów. Na granicach należy pobrać o tyle więcej elementów ile wynosi suma długości najdłuższego filtra i jego przesunięcia. Część wątków uczestniczy tylko w ładowaniu danych do pamięci współdzielonej bez wykonywania obliczeń. Ze względu na małą długość filtrów w porównaniu do liczby wątków nie wpływa to znacząco na efektywność. Rysunek 24: Obliczanie współczynników falkowych z wykorzystaniem pamięci współdzielonej 41

45 Na rysunku 24 przedstawiony został schemat obliczania współczynników falkowych z wykorzystaniem pamięci współdzielonej. Wykorzystana musi być funkcja syncthreads() synchronizująca wątki w ramach bloku. Wątki nie biorące udziału w obliczaniu współczynników kończą działanie po wywołaniu funkcji syncthreads(). Wszystkie wątki przy liczeniu transformaty wykorzystują współczynniki filtrów dolno i górnoprzepustowego. Naturalnym miejscem do przechowywania tych wartości jest pamięć stałych. Współczynniki filtrów są umieszczane w pamięci stałych przez hosta przed uruchomieniem kerneli. Obliczenie transformaty dla sygnałów wielowymiarowych odbywa się poprzez osobne obliczenie transformaty jednowymiarowej po każdym z wymiarów. Dla obrazu wykonujemy więc najpierw obliczenie transformaty po wierszach, a następnie po kolumnach. Dzięki wykorzystaniu pamięci współdzielonej znacznie uprościła się implementacja poszczególnych kerneli. Każdy z nich ładuje najpierw dane w ramach bloku do pamięci współdzielonej. Na rysunku 25 pokazane jest ładowanie danych w przypadku transformaty obrazu. Należy oczywiście uwzględnić dodatkowe elementy na granicach. Rysunek 25: Załadowanie danych do pamięci współdzielonej w przypadku transformaty falkowej obrazu Po załadowaniu danych do pamięci współdzielonej, możemy zastosować algorytm konwolucji wykorzystujący współczynniki z pamięci współdzielonej i współczynniki filtrów z pamięci stałych. Dzięki wstępnemu załadowaniu danych do tej pamięci nie jest wymagane złożone indeksowanie. Kernele dla transformaty jedno, dwu i trójwymiarowej mają identyczną strukturę. W pierwszym kroku ładują one dane do pamięci współdzielonej, np. w sekwencji wideo ładowana jest kolumna danej ramki. Po zsynchronizowaniu wątków wywoływana jest funkcja obliczająca i-ty współczynnik falkowy na podstawie danych zgromadzonych w pamięci współdzielonej. Następnie otrzymany współczynnik jest zapisywany w pamięci globalnej przeznaczonej na wynik. 42

46 Transformata odwrotna działa w analogiczny sposób z tą różnicą, że każdy z wątków oblicza tylko jeden współczynnik. Musi on najpierw załadować do pamięci współdzielonej jeden współczynnik wysokich częstotliwości i jeden współczynnik niskich częstotliwości. Między pobrane wartości wstawiane są od razu zera (rysunek 26). Następnie wywoływana jest generyczna funkcja obliczająca transformatę odwrotną na podstawie przekazanych w pamięci współdzielonej danych. Zrekonstruowany element zapisywany jest w pamięci globalnej. Rysunek 26: Obliczenie transformaty odwrotnej z załadowaniem danych pasma niskich i wysokich częstotliwości do pamięci współdzielonej Posiadając zaimplementowane funkcje kerneli należy dla wybranych danych wybrać odpowiednią ilość bloków i wywołać funkcje kerneli. Trzeba również wziąć pod uwagę liczbę poziomów dekompozycji. Poniżej umieściłem kod wywoływany przy obliczaniu transformaty falkowej dla kilku poziomów dekompozycji w obrazie. while ( l e v e l s > 0) { // C a l c u a l t e dimensions of b l o c k f o r row transform... // C a l c u a l t e dwt on d e v i c e f o r each row forwardtransform2drow<<<numblocks, threadsperblock > > >(...); // C a l c u a l t e dimensions of b l o c k f o r row transform... // C a l c u a l t e dwt on d e v i c e f o r each column forwardtransform2dcolumn<<<numblocks, threadsperblock > > >(...); } currwidth = ( currwidth +1) / 2 ; currheight = ( currheight +1) / 2 ; 43

47 7.4 Mechanizmy pomiaru czasu Aplikacja posiada wbudowane w siebie mechanizmy pomiaru czasu wykonania poszczególnych kroków algorytmu kompresji/dekompresji. Dzięki temu możliwe jest określenie zysku uzyskanego przy implementacji CUDA. Standardowym podejściem przy pomiarze czasu jest wykorzystanie funkcji clock() z biblioteki time.h. Taki zegar posiada jednak niską rozdzielczość przez co nie mógł być wykorzystany w mojej aplikacji. Do pomiaru czasu wykonania przy pomocy zegara CPU można wykorzystać funkcję clock gettime(), która posiada większą rozdzielczość. Należy jednak mieć na uwadze, że część wywołań CUDA jest asynchroniczna (m.in. wywołania kerneli) [13]. Aby możliwy był poprawny pomiar czasu wykonania, należy wówczas wywołać przed zatrzymaniem zegara funkcję cudathreadsynchronize(). Można tego uniknąć wykorzystując CUDA Event API, które pozwala na tworzenie zdarzeń (cudaeventcreate) i zarejestrowanie czasu (cudaeventrecord) poprzez znacznik czasu. Synchronizacja wywołań asynchronicznych nie jest wówczas wymagana. Taki właśnie sposób wykorzystałem w swojej aplikacji. Pomiarowi czasu zostały poddane przedstawione na rysunku 27 kroki algorytmu kompresji. Dla implementacji CUDA uwzględniłem czas konieczny na zaalokowanie pamięci urządzenia oraz na wykonanie transferów. Kwantyzacja i kodowanie arytmetyczne zostały uwzględnione razem, ze względu na sposób implementacji. Współczynniki falkowe są kwantyzowane jeden po drugim i od razu kodowane koderem arytmetycznym. Nie jest więc możliwy oddzielny pomiar czasu wykonania tych kroków. Rysunek 27: Kroki algorytmu kompresji poddane pomiarowi czasu dla implementacji CPU i GPU 44

48 Rysunek 28: Kroki algorytmu dekompresji poddane pomiarowi czasu dla implementacji CPU i GPU Analogiczny pomiar czasu działania jest zaimplementowany przy algorytmie dekompresji (rysunek 28). Dekodowanie arytmetyczne oraz dekwantyzacja została uwzględniona razem. Zdekodowane koderem arytmetycznym symbole są od razu poddawane dekwantyzacji. Nie jest wykorzystywany żaden pośredni bufor przez co nie jest możliwy oddzielny pomiar czasu. Na obu rysunkach 27 i 28 przedstawiłem również bloki związane z odczytem i zapisem przy wykorzystaniu biblioteki OpenCV. W kroku tym ujęty jest czas wykorzystywany do odpowiedniego sformatowania danych. Przedstawiony pomiar czasu nie obejmuje całości czasu wykonania programu. Nie są w nim uwzględnione, np. czasy związane z wykonaniem parsowania argumentów wywołania. Czas ten jednak jest zaniedbywalnie mały w porównaniu z czasem wykonania poszczególnych kroków kompresji/dekompresji. 45

49 8 Weryfikacja W tym rozdziale przedstawione są metody weryfikacji rozwiązania wraz z uzyskanymi wynikami. Zaimplementowany kompresor został przetestowany pod względem skuteczności kompresji oraz szybkości działania. Zbadano efektywność kompresji dla poszczególnych funkcji falkowych i kwantyzatorów. Na potrzeby porównania implementacji CUDA zmierzono czas wykonania dla implementacji na procesorze CPU i GPU. Wykorzystano wbudowane w aplikację mechanizmy pomiaru czasu działania poszczególnych kroków algorytmu. Dodatkowo wykonane zostały syntetyczne testy dla transformaty falkowej sprawdzające precyzję obliczeń na procesorze GPU. Każdy z testów został opisany w oddzielnym podrozdziale wraz z krótkim opisem metodyki wykonania testu. Na początku przedstawiam wybrany zbiór testowy obrazów i sekwencji wideo. 8.1 Zbiór testowy lena 512x512 (768kB) lena gray 512x512 (256kB) barbara 512x512 (256kB) 46

50 pw 1024x1024 (3MB) globe 2048x2048 (12MB) moon 4096x4096 (48MB) klip wideo crysis 2 640x360, 256 klatek (168,75 MB) 512x256, 256 klatek (96 MB) 256x128, 256 klatek (24 MB) 47

51 8.2 Precyzja obliczeń Wyniki obliczeń wykonywane na procesorze GPU mogą nieco różnić się od wyników na procesorze GPU. Wykorzystywana przeze mnie karta graficzna wspiera liczby zmiennoprzecinkowe pojedynczej precyzji zbliżone do standardu IEEE 754. W tabeli 5 znajdują się wyniki dla wykonanego testu precyzji obliczeń. Przetestowana została transformata i transformata odwrotna dla sygnałów jedno, dwu i trójwymiarowych z zadaną liczbą poziomów dekompozycji. Danymi wejściowymi były losowe liczby całkowite z zakresu [0-255] (tak jak wartości jasności pikseli). Obliczony został całkowity błąd bezwzględny oraz błąd na symbol. Uzyskane wyniki świadczą o niewielkiej rozbieżności precyzji obliczeń na GPU. Dyskretna transformata falkowa jest stabilna numerycznie i niewielkie niedokładności nie wpływają na uzyskane wyniki. Liczba poziomów dekompozycji Wymiary Całkowity błąd Błąd na symbol DWT 1D DWT 2D x DWT 3D x 512 x IDWT 1D IDWT 2D x IDWT 3D x 512 x Tabela 5: Wyniki testów porównujących precyzję obliczeń transformaty CPU i GPU 8.3 Efektywność kompresji Efektywność kompresji stratnej jest oceniana pod dwoma kryteriami: uzyskanej liczby bitów (rate) oraz zniekształceń (distortion). Miarę uzyskanej liczby bitów określa się przy pomocy stopnia kompresji wyrażającego stosunek liczby bitów danych oryginalnych do liczby bitów uzyskanych w wyniku kompresji. Często korzysta się również z pojęcia bitrate określającego liczbę bitów przypadających na jeden symbol zakodowanego sygnału. W przypadku kompresji obrazów i sekwencji wideo jest to liczba bitów przypadających na jeden piksel (bpp - bit per pixel). Do opisania zniekształceń wybrałem powszechnie wykorzystywaną miarę PSNR (Peak signal-to-noise ratio). Wyraża ona stosunek maksymalnej możliwej energii sygnału i energii szumu (w tym przypadku zniekształceń). Wykorzystuje się w niej skalę logarytmiczną, ze względu na różną dynamikę sygnałów, dla których używa się tej miary. Do opisania szumu wykorzystywany jest opisany wcześniej błąd średniokwadratowy MSE 6. Maksymalna energia sygnału MAX to maksymalna możliwa wartość jasności piksela (dla 8 bitów na piksel to 255). 48

52 Wzór opisujący PSNR ma następującą postać: ( ) MAX 2 P SNR = 10 log 10 MSE ( ) MAX = 20 log 10 MSE (12) Dla obrazów barwnych miara PSNR jest również obliczona dla każdego z kanałów osobno. W testach efektywności kompresji najlepiej jednak korzystać z obrazów w odcieniach szarości, ponieważ uzyskujemy możliwość łatwego porównania skuteczności kompresji z innymi rozwiązaniami. Dodatkowo dla obrazów barwnych jest obliczana miara PSNR po sprowadzeniu obrazu do odcieni szarości. Warto zauważyć, że przy braku zniekształceń błąd średniokwadratowy wynosi 0 i miara PSNR dąży do nieskończoności. W pracy [15], można znaleźć wiele innych miar syntetycznych, jak również miar subiektywnych. W wykonanych przeze mnie testach aplikacji ograniczyłem się do najczęściej wykorzystywanej miary PSNR. W koder wbudowane są mechanizmy pomiaru powstałych w wyniku kompresji zniekształceń, według miary PSNR. Liczba bitów jest obliczana przez pomiar długości powstałego pliku wynikowego. Na podstawie uzyskanej liczby bitów określane jest również odchylenie uzyskanego stopnia kompresji od zadanego. Wszystkie te informacje można uzyskać po podaniu odpowiedniego argumentu wywołania programu. Jako pierwsze przedstawię wyniki porównania dwóch zaimplementowanych kwantyzatorów: kwantyzatora równomiernego (UTQ) i kwantyzatora równomiernego z rozszerzonym przedziałem zerowym (DUTQ). Obrazem testowym jest lena w odcieniach szarości. Dla lepszego zobrazowania uzyskanych wyników wykorzystam przedstawione wcześniej krzywe R-D (rysunek 29). Rysunek 29: Wyniki kompresji dla kwantyzatorów UTQ i DUTQ 49

53 Zgodnie z przewidywaniami, wykorzystanie kwantyzatora z rozszerzonym przedziałem zerowym umożliwiło uzyskanie mniejszych zniekształceń dla wyższych stopni kompresji (0.5 PSNR dla stopnia 64 i ponad 0.8 PSNR dla stopnia 128). Wraz z wzrostem stopnia kompresji silniej kwantyzujemy współczynniki i rozszerzony przedział zerowy kwantyzuje więcej współczynników do zera. Przy niskiej kompresji wykorzystanie tego kwantyzatora nie daje lepszych wyników. Dalsze testy były przeprowadzane przy użyciu kwantyzatora z rozszerzonym przedziałem zerowym, który charakteryzuje się lepszym stopniem kompresji. Kolejnym testem, który przeprowadziłem było określenie optymalnej liczby poziomów dekompozycji przy kompresji obrazów i plików wideo. Do testów wybrałem obraz lena w odcieniach szarości oraz klip testowy o rozmiarze ramki 640x360 pikseli. Testy zostały wykonane przy użyciu banku filtrów antonini dla stopnia kompresji 32 dla obrazu i 32 dla sekwencji wideo. Pomiarowi został również poddany uzyskany stopień kompresji. W tabeli 6 znajdują się uzyskane wyniki. Dla sekwencji wideo zostały uwzględnione uzyskane wyniki dla poszczególnych kanałów. Poziomy Lena Crysis dekomp. Uzyskany PSNR Uzyskany stopień stopień PSNR PSNR-C Y PSNR-C b PSNR-C r Tabela 6: Wyniki testów porównujących wpływ liczby poziomów dekompozycji na stopień kompresji Przy kompresji obrazu zadowalające wyniki uzyskujemy dopiero po wykonaniu przynajmniej trzy poziomowej dekompozycji. Wartością optymalną jest 5 i taką też przyjąłem jako domyślną w mojej aplikacji. 4 Wraz z zwiększeniem liczby poziomów dekompozycji zwiększa się ilość podpasm, a co za tym idzie ilość kwantyzatorów, których dane trzeba przesłać (szerokość przedziału kwantyzacji itp.). Należy mieć również na uwadze to, że większa liczba poziomów dekompozycji zwiększa koszt obliczenia transformaty falkowej. W przypadku kompresji wideo optymalną wartość uzyskujemy przy trzypoziomowej dekompozycji. Najważniejsze dla odbiorcy dane zawarte są w kanale z jasnością (Y). Dla każdego z 3 kanałów przeznaczona jest inna ilość bitów. Kanał Y uzyskuje 0.8 budżetu bitowego natomiast kanały C b i C r dostają po 0.1 budżetu bitów. Wyższa jakość kompresji dla kanału z chrominancją wynika z cech zastosowanej transformaty kolorów. 4 Inne obrazy mogą mieć inną wartość optymalną jednak będzie ona blisko tej wartości. 50

54 Kolejną zbadaną przeze mnie kwestią były wybrane filtry falkowe. W tabeli 7 przedstawione są wyniki testów dla zadanych stopni kompresji przy obrazie barbara. Obraz był kompresowany przy użyciu 5 poziomów dekompozycji. Obraz barbara posiada znacznie więcej krawędzi niż obraz lena, w którym przeważały dość łagodne gradienty. Skutkuje to oczywiście niższą skutecznością kompresji. Stopień kompr. haar daub4 cdf97 antonini Tabela 7: Wyniki testów porównujących wybrane filtry falkowe według miary PSNR Najlepszymi zestawami filtrów okazały się filtry cdf97 i antonini. Uzyskane przez nie wyniki są prawie takie same. Różnice w ilości bitów i uzyskanej miary PSNR są bardzo małe. Jako domyślny filtr falkowy ustaliłem filtr antonini. Rysunek 30 pokazuje fragment uzyskanego w wyniku kompresji obrazu. Rysunek 30: Wyniki ośmiokrotnej kompresji dla różnych filtrów: A - oryginał, B - haar, C - daub04, D - cdf97 51

55 Stopień kompresji lena lena gray barbara pw globe moon PSNR PSNR-Y PSNR-C b PSNR-C r PSNR PSNR-Y PSNR-C b PSNR-C r PSNR PSNR-Y PSNR-C b PSNR-C r PSNR PSNR-Y PSNR-C b PSNR-C r PSNR PSNR-Y PSNR-C b PSNR-C r PSNR PSNR-Y PSNR-C b PSNR-C r Tabela 8: Wyniki testów kompresji obrazów dla stopni 4, 8, 16, 32, 64 i 128 według miary PSNR. PSNR dla obrazów barwnych został obliczony po przekształceniu na przestrzeń barw Y C b C r, a także po przekształceniu na obraz monochromatyczny. Stopień kompresji crysis 512x256 PSNR PSNR-Y PSNR-C b PSNR-C r PSNR PSNR-Y PSNR-C b PSNR-C r PSNR PSNR-Y PSNR-C b PSNR-C r Tabela 9: Wyniki testów efektywności kompresji sekwencji wideo crysis 2 dla stopni 32, 64 i 128 według miary PSNR. PSNR został obliczony po przekształceniu na przestrzeń barw Y C b C r, a także po przekształceniu na sekwencję obrazów monochromatyczną. 52

56 8.4 Szybkość działania Dzięki wbudowanym w aplikację mechanizmom pomiaru czasu udało się precyzyjnie określić ile czasu zajmuje wykonanie poszczególnych kroków algorytmu kompresji/dekompresji. Głównym celem było oczywiście porównanie efektywności implementacji CUDA z implementacją CPU. Każdy z testów czasu działania był pięciokrotnie powtarzany, a z zmierzonych czasów była wyciągnięta średnia. Jako pierwszą porównałem efektywność działania dla obrazów, różnych rozmiarów. Wybrałem obrazy barwne, aby określić korzyść z wykorzystania obliczeń GPU. Szczegółowe wyniki przedstawione są w tabelach 10, 11, 12, 13 na końcu podrozdziału. Na wykresach 31 i 32 przedstawiłem czas działania dla kompresji i dekompresji obrazów dla poszczególnych rozmiarów. Dla obrazu o rozmiarze 512x512 pikseli nie ma w praktyce zysku z wykorzystania implementacji GPU. Przy obrazach większego rozmiaru zysk staje się zauważalny. Rysunek 31: Czas kompresji obrazów dla implementacji CPU i CUDA Rysunek 32: Czas dekompresji obrazów dla implementacji CPU i CUDA 53

57 Jak da się zauważyć zysk przy dekompresji jest znacznie większy niż przy kompresji. Wynika to z tego, iż większą część czasu działania przy kompresji zajmuje wykonanie optymalizacji RD (rysunki 33 i 34). Dlatego pomimo blisko dziesięciokrotnego przyśpieszenia obliczania transformaty falkowej dla obrazu 4096x4096 uzyskałem wzrost wydajności rzędu 40 procent. Dekompresja nie wymaga wykonania optymalizacji RD, więc przyśpieszenie transformaty odwrotnej skutkuje ponad trzykrotnym przyśpieszeniem czasu działania (rysunki 35 i 36). Implementacja transformaty kolorów na procesorze GPU jest średnio kilkunastokrotnie szybsza niż na CPU. Jednak ze względu na znikomy koszt w porównaniu z pozostałymi krokami nie wpływa ona znacząco na całkowitą efektywność kompresora. Należy również zwrócić uwagę na koszty alokacji i transferów danych na urządzeniu. Dla transformaty dwuwymiarowej koszty alokacji i transferów stanowią do 20 procent całego czasu przetwarzania na GPU. Przy dekompresji znaczący czas zaczyna zajmować zapis do innego formatu pliku wykonywany przez bibliotekę OpenCV. Rysunek 33: Czas wykonania kompresji dla implementacji CPU Rysunek 34: Czas wykonania kompresji dla implementacji CUDA 54

58 Rysunek 35: Czas wykonania dekompresji dla implementacji CPU Rysunek 36: Czas wykonania dekompresji dla implementacji CUDA Dla kompresji i dekompresji sekwencji wideo uzyskałem analogiczne wyniki (rysunki 37 i 38) jak dla obrazów. Szczegółowe wyniki znajdują się w tabelach 14, 15, 16 i 17. Zdecydowaną większość czasu kompresji zajmuje wykonanie optymalizacji RD (dla sekwencji wideo 640x360 ponad 70 procent). Da się również zauważyć mniejszy stosunek czasu obliczenia transformaty na CPU do czasu obliczenia na GPU. Dla transformaty trójwymiarowej wynosi on około trzech. Mniejsza efektywność ma swoje źródło w dostępie do pamięci. Przy transformacie trójwymiarowej dostęp do pamięci zazwyczaj nie odbywa się po kolejnych fragmentach pamięci 5 przez co nie jest wykorzystywana technika memory coalescing. Współczynniki ładowane do pamięci współdzielonej bloku są zazwyczaj fizycznie rozroszone w pamięci głównej. 5 dostęp po kolejnych elementach w pamięci ma miejsce przy transformacie po wierszach 55

59 Rysunek 37: Czas kompresji wideo dla implementacji CPU i CUDA Rysunek 38: Czas dekompresji wideo dla implementacji CPU i CUDA Rysunek 39: Czas kompresji wideo dla implementacji CUDA Rysunek 40: Czas dekompresji wideo dla implementacji CUDA 56

Założenia i obszar zastosowań. JPEG - algorytm kodowania obrazu. Geneza algorytmu KOMPRESJA OBRAZÓW STATYCZNYCH - ALGORYTM JPEG

Założenia i obszar zastosowań. JPEG - algorytm kodowania obrazu. Geneza algorytmu KOMPRESJA OBRAZÓW STATYCZNYCH - ALGORYTM JPEG Założenia i obszar zastosowań KOMPRESJA OBRAZÓW STATYCZNYCH - ALGORYTM JPEG Plan wykładu: Geneza algorytmu Założenia i obszar zastosowań JPEG kroki algorytmu kodowania obrazu Założenia: Obraz monochromatyczny

Bardziej szczegółowo

2. Próbkowanie Sygnały okresowe (16). Trygonometryczny szereg Fouriera (17). Częstotliwość Nyquista (20).

2. Próbkowanie Sygnały okresowe (16). Trygonometryczny szereg Fouriera (17). Częstotliwość Nyquista (20). SPIS TREŚCI ROZDZIAŁ I SYGNAŁY CYFROWE 9 1. Pojęcia wstępne Wiadomości, informacje, dane, sygnały (9). Sygnał jako nośnik informacji (11). Sygnał jako funkcja (12). Sygnał analogowy (13). Sygnał cyfrowy

Bardziej szczegółowo

Kodowanie transformacyjne. Plan 1. Zasada 2. Rodzaje transformacji 3. Standard JPEG

Kodowanie transformacyjne. Plan 1. Zasada 2. Rodzaje transformacji 3. Standard JPEG Kodowanie transformacyjne Plan 1. Zasada 2. Rodzaje transformacji 3. Standard JPEG Zasada Zasada podstawowa: na danych wykonujemy transformacje która: Likwiduje korelacje Skupia energię w kilku komponentach

Bardziej szczegółowo

mgr inż. Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 4, strona 1. GOLOMBA I RICE'A

mgr inż. Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 4, strona 1. GOLOMBA I RICE'A mgr inż. Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 4, strona 1. KOMPRESJA ALGORYTMEM ARYTMETYCZNYM, GOLOMBA I RICE'A Idea algorytmu arytmetycznego Przykład kodowania arytmetycznego Renormalizacja

Bardziej szczegółowo

Kompresja Kodowanie arytmetyczne. Dariusz Sobczuk

Kompresja Kodowanie arytmetyczne. Dariusz Sobczuk Kompresja Kodowanie arytmetyczne Dariusz Sobczuk Kodowanie arytmetyczne (lata 1960-te) Pierwsze prace w tym kierunku sięgają początków lat 60-tych XX wieku Pierwszy algorytm Eliasa nie został opublikowany

Bardziej szczegółowo

Według raportu ISO z 1988 roku algorytm JPEG składa się z następujących kroków: 0.5, = V i, j. /Q i, j

Według raportu ISO z 1988 roku algorytm JPEG składa się z następujących kroków: 0.5, = V i, j. /Q i, j Kompresja transformacyjna. Opis standardu JPEG. Algorytm JPEG powstał w wyniku prac prowadzonych przez grupę ekspertów (ang. Joint Photographic Expert Group). Prace te zakończyły się w 1991 roku, kiedy

Bardziej szczegółowo

Kodowanie i kompresja Streszczenie Studia Licencjackie Wykład 11,

Kodowanie i kompresja Streszczenie Studia Licencjackie Wykład 11, 1 Kwantyzacja skalarna Kodowanie i kompresja Streszczenie Studia Licencjackie Wykład 11, 10.05.005 Kwantyzacja polega na reprezentowaniu dużego zbioru wartości (być może nieskończonego) za pomocą wartości

Bardziej szczegółowo

Kompresja danych DKDA (7)

Kompresja danych DKDA (7) Kompresja danych DKDA (7) Marcin Gogolewski marcing@wmi.amu.edu.pl Uniwersytet im. Adama Mickiewicza w Poznaniu Poznań, 22 listopada 2016 1 Kwantyzacja skalarna Wprowadzenie Analiza jakości Typy kwantyzatorów

Bardziej szczegółowo

Praca dyplomowa magisterska

Praca dyplomowa magisterska Praca dyplomowa magisterska Implementacja algorytmów filtracji adaptacyjnej o strukturze transwersalnej na platformie CUDA Dyplomant: Jakub Kołakowski Opiekun pracy: dr inż. Michał Meller Plan prezentacji

Bardziej szczegółowo

Transformata Fouriera

Transformata Fouriera Transformata Fouriera Program wykładu 1. Wprowadzenie teoretyczne 2. Algorytm FFT 3. Zastosowanie analizy Fouriera 4. Przykłady programów Wprowadzenie teoretyczne Zespolona transformata Fouriera Jeżeli

Bardziej szczegółowo

Programowanie Współbieżne

Programowanie Współbieżne Programowanie Współbieżne Agnieszka Łupińska 5 października 2016 Hello World! helloworld.cu: #include global void helloworld(){ int thid = (blockidx.x * blockdim.x) + threadidx.x; printf("hello

Bardziej szczegółowo

dr inż. Jarosław Forenc

dr inż. Jarosław Forenc Informatyka 2 Politechnika Białostocka - Wydział Elektryczny Elektrotechnika, semestr III, studia stacjonarne I stopnia Rok akademicki 2010/2011 Wykład nr 7 (24.01.2011) dr inż. Jarosław Forenc Rok akademicki

Bardziej szczegółowo

Podstawy Informatyki Systemy sterowane przepływem argumentów

Podstawy Informatyki Systemy sterowane przepływem argumentów Podstawy Informatyki alina.momot@polsl.pl http://zti.polsl.pl/amomot/pi Plan wykładu 1 Komputer i jego architektura Taksonomia Flynna 2 Komputer i jego architektura Taksonomia Flynna Komputer Komputer

Bardziej szczegółowo

Przedmowa 11 Ważniejsze oznaczenia 14 Spis skrótów i akronimów 15 Wstęp 21 W.1. Obraz naturalny i cyfrowe przetwarzanie obrazów 21 W.2.

Przedmowa 11 Ważniejsze oznaczenia 14 Spis skrótów i akronimów 15 Wstęp 21 W.1. Obraz naturalny i cyfrowe przetwarzanie obrazów 21 W.2. Przedmowa 11 Ważniejsze oznaczenia 14 Spis skrótów i akronimów 15 Wstęp 21 W.1. Obraz naturalny i cyfrowe przetwarzanie obrazów 21 W.2. Technika obrazu 24 W.3. Normalizacja w zakresie obrazu cyfrowego

Bardziej szczegółowo

Programowanie procesorów graficznych GPGPU

Programowanie procesorów graficznych GPGPU Programowanie procesorów graficznych GPGPU 1 GPGPU Historia: lata 80 te popularyzacja systemów i programów z graficznym interfejsem specjalistyczne układy do przetwarzania grafiki 2D lata 90 te standaryzacja

Bardziej szczegółowo

Cyfrowe przetwarzanie i kompresja danych

Cyfrowe przetwarzanie i kompresja danych Cyfrowe przetwarzanie i kompresja danych dr inż.. Wojciech Zając Wykład 5. Dyskretna transformata falkowa Schemat systemu transmisji danych wizyjnych Źródło danych Przetwarzanie Przesył Przetwarzanie Prezentacja

Bardziej szczegółowo

Kodowanie podpasmowe. Plan 1. Zasada 2. Filtry cyfrowe 3. Podstawowy algorytm 4. Zastosowania

Kodowanie podpasmowe. Plan 1. Zasada 2. Filtry cyfrowe 3. Podstawowy algorytm 4. Zastosowania Kodowanie podpasmowe Plan 1. Zasada 2. Filtry cyfrowe 3. Podstawowy algorytm 4. Zastosowania Zasada ogólna Rozkład sygnału źródłowego na części składowe (jak w kodowaniu transformacyjnym) Wada kodowania

Bardziej szczegółowo

Kwantyzacja wektorowa. Kodowanie różnicowe.

Kwantyzacja wektorowa. Kodowanie różnicowe. Kwantyzacja wektorowa. Kodowanie różnicowe. Kodowanie i kompresja informacji - Wykład 7 12 kwietnia 2010 Kwantyzacja wektorowa wprowadzenie Zamiast kwantyzować pojedyncze elementy kwantyzujemy całe bloki

Bardziej szczegółowo

Kompresja dźwięku w standardzie MPEG-1

Kompresja dźwięku w standardzie MPEG-1 mgr inż. Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 7, strona 1. Kompresja dźwięku w standardzie MPEG-1 Ogólne założenia kompresji stratnej Zjawisko maskowania psychoakustycznego Schemat blokowy

Bardziej szczegółowo

Temat: Algorytm kompresji plików metodą Huffmana

Temat: Algorytm kompresji plików metodą Huffmana Temat: Algorytm kompresji plików metodą Huffmana. Wymagania dotyczące kompresji danych Przez M oznaczmy zbiór wszystkich możliwych symboli występujących w pliku (alfabet pliku). Przykład M = 2, gdy plik

Bardziej szczegółowo

Teoria przetwarzania A/C i C/A.

Teoria przetwarzania A/C i C/A. Teoria przetwarzania A/C i C/A. Autor: Bartłomiej Gorczyński Cyfrowe metody przetwarzania sygnałów polegają na przetworzeniu badanego sygnału analogowego w sygnał cyfrowy reprezentowany ciągiem słów binarnych

Bardziej szczegółowo

Metody numeryczne Technika obliczeniowa i symulacyjna Sem. 2, EiT, 2014/2015

Metody numeryczne Technika obliczeniowa i symulacyjna Sem. 2, EiT, 2014/2015 Metody numeryczne Technika obliczeniowa i symulacyjna Sem. 2, EiT, 2014/2015 1 Metody numeryczne Dział matematyki Metody rozwiązywania problemów matematycznych za pomocą operacji na liczbach. Otrzymywane

Bardziej szczegółowo

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

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

Bardziej szczegółowo

Fundamentals of Data Compression

Fundamentals of Data Compression Załącznik nr 7 do Zarządzenia Rektora nr 10/12 z dnia 21 lutego 2012r. KARTA MODUŁU / KARTA PRZEDMIOTU Kod modułu Nazwa modułu Nazwa modułu w języku angielskim Obowiązuje od roku akademickiego 2012/2013

Bardziej szczegółowo

Przetwarzanie i transmisja danych multimedialnych. Wykład 7 Transformaty i kodowanie. Przemysław Sękalski.

Przetwarzanie i transmisja danych multimedialnych. Wykład 7 Transformaty i kodowanie. Przemysław Sękalski. Przetwarzanie i transmisja danych multimedialnych Wykład 7 Transformaty i kodowanie Przemysław Sękalski sekalski@dmcs.pl Politechnika Łódzka Katedra Mikroelektroniki i Technik Informatycznych DMCS Wykład

Bardziej szczegółowo

Algorytm. a programowanie -

Algorytm. a programowanie - Algorytm a programowanie - Program komputerowy: Program komputerowy można rozumieć jako: kod źródłowy - program komputerowy zapisany w pewnym języku programowania, zestaw poszczególnych instrukcji, plik

Bardziej szczegółowo

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

Porównanie wydajności CUDA i OpenCL na przykładzie równoległego algorytmu wyznaczania wartości funkcji celu dla problemu gniazdowego Porównanie wydajności CUDA i OpenCL na przykładzie równoległego algorytmu wyznaczania wartości funkcji celu dla problemu gniazdowego Mariusz Uchroński 3 grudnia 2010 Plan prezentacji 1. Wprowadzenie 2.

Bardziej szczegółowo

Technika audio część 2

Technika audio część 2 Technika audio część 2 Wykład 12 Projektowanie cyfrowych układów elektronicznych Mgr inż. Łukasz Kirchner lukasz.kirchner@cs.put.poznan.pl http://www.cs.put.poznan.pl/lkirchner Wprowadzenie do filtracji

Bardziej szczegółowo

KOMPRESJA OBRAZÓW STATYCZNYCH - ALGORYTM JPEG

KOMPRESJA OBRAZÓW STATYCZNYCH - ALGORYTM JPEG KOMPRESJA OBRAZÓW STATYCZNYCH - ALGORYTM JPEG Joint Photographic Expert Group - 1986 ISO - International Standard Organisation CCITT - Comité Consultatif International de Téléphonie et Télégraphie Standard

Bardziej szczegółowo

0 + 0 = 0, = 1, = 1, = 0.

0 + 0 = 0, = 1, = 1, = 0. 5 Kody liniowe Jak już wiemy, w celu przesłania zakodowanego tekstu dzielimy go na bloki i do każdego z bloków dodajemy tak zwane bity sprawdzające. Bity te są w ścisłej zależności z bitami informacyjnymi,

Bardziej szczegółowo

ZADANIE 1. Rozwiązanie:

ZADANIE 1. Rozwiązanie: EUROELEKTR Ogólnopolska Olimpiada Wiedzy Elektrycznej i Elektronicznej Rok szkolny 200/20 Rozwiązania zadań dla grupy teleinformatycznej na zawody II. stopnia ZNIE ramka logiczna w technologii MOS składa

Bardziej szczegółowo

LABORATORIUM PROCESORY SYGNAŁOWE W AUTOMATYCE PRZEMYSŁOWEJ. Zasady arytmetyki stałoprzecinkowej oraz operacji arytmetycznych w formatach Q

LABORATORIUM PROCESORY SYGNAŁOWE W AUTOMATYCE PRZEMYSŁOWEJ. Zasady arytmetyki stałoprzecinkowej oraz operacji arytmetycznych w formatach Q LABORAORIUM PROCESORY SYGAŁOWE W AUOMAYCE PRZEMYSŁOWEJ Zasady arytmetyki stałoprzecinkowej oraz operacji arytmetycznych w formatach Q 1. Zasady arytmetyki stałoprzecinkowej. Kody stałopozycyjne mają ustalone

Bardziej szczegółowo

Kodowanie i kompresja Streszczenie Studia dzienne Wykład 9,

Kodowanie i kompresja Streszczenie Studia dzienne Wykład 9, 1 Kody Tunstalla Kodowanie i kompresja Streszczenie Studia dzienne Wykład 9, 14.04.2005 Inne podejście: słowa kodowe mają ustaloną długość, lecz mogą kodować ciągi liter z alfabetu wejściowego o różnej

Bardziej szczegółowo

Programowanie kart graficznych

Programowanie kart graficznych 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

Bardziej szczegółowo

Wybrane metody kompresji obrazów

Wybrane metody kompresji obrazów Wybrane metody kompresji obrazów Celem kodowania kompresyjnego obrazu jest redukcja ilości informacji w nim zawartej. Redukcja ta polega na usuwaniu informacji nadmiarowej w obrazie, tzw. redundancji.

Bardziej szczegółowo

5. Rozwiązywanie układów równań liniowych

5. Rozwiązywanie układów równań liniowych 5. Rozwiązywanie układów równań liniowych Wprowadzenie (5.1) Układ n równań z n niewiadomymi: a 11 +a 12 x 2 +...+a 1n x n =a 10, a 21 +a 22 x 2 +...+a 2n x n =a 20,..., a n1 +a n2 x 2 +...+a nn x n =a

Bardziej szczegółowo

Budowa Mikrokomputera

Budowa Mikrokomputera Budowa Mikrokomputera Wykład z Podstaw Informatyki dla I roku BO Piotr Mika Podstawowe elementy komputera Procesor Pamięć Magistrala (2/16) Płyta główna (ang. mainboard, motherboard) płyta drukowana komputera,

Bardziej szczegółowo

Python: JPEG. Zadanie. 1. Wczytanie obrazka

Python: JPEG. Zadanie. 1. Wczytanie obrazka Python: JPEG Witajcie! Jest to kolejny z serii tutoriali uczący Pythona, a w przyszłości być może nawet Cythona i Numby Jeśli chcesz nauczyć się nowych, zaawansowanych konstrukcji to spróbuj rozwiązać

Bardziej szczegółowo

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

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja

Bardziej szczegółowo

Spis treści. I. Skuteczne. Od autora... Obliczenia inżynierskie i naukowe... Ostrzeżenia...XVII

Spis treści. I. Skuteczne. Od autora... Obliczenia inżynierskie i naukowe... Ostrzeżenia...XVII Spis treści Od autora..................................................... Obliczenia inżynierskie i naukowe.................................. X XII Ostrzeżenia...................................................XVII

Bardziej szczegółowo

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk Podstawy informatyki Informatyka stosowana - studia niestacjonarne Grzegorz Smyk Wydział Inżynierii Metali i Informatyki Przemysłowej Akademia Górniczo Hutnicza im. Stanisława Staszica w Krakowie, Materiał

Bardziej szczegółowo

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia.

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia. ARYTMETYKA BINARNA ROZWINIĘCIE DWÓJKOWE Jednym z najlepiej znanych sposobów kodowania informacji zawartej w liczbach jest kodowanie w dziesiątkowym systemie pozycyjnym, w którym dla przedstawienia liczb

Bardziej szczegółowo

teoria informacji Kanały komunikacyjne, kody korygujące Mariusz Różycki 25 sierpnia 2015

teoria informacji Kanały komunikacyjne, kody korygujące Mariusz Różycki 25 sierpnia 2015 teoria informacji Kanały komunikacyjne, kody korygujące Mariusz Różycki 25 sierpnia 2015 1 wczoraj Wprowadzenie matematyczne. Entropia i informacja. Kodowanie. Kod ASCII. Stopa kodu. Kody bezprefiksowe.

Bardziej szczegółowo

LABORATORIUM AKUSTYKI MUZYCZNEJ. Ćw. nr 12. Analiza falkowa dźwięków instrumentów muzycznych. 1. PODSTAWY TEORETYCZNE ANALIZY FALKOWEJ.

LABORATORIUM AKUSTYKI MUZYCZNEJ. Ćw. nr 12. Analiza falkowa dźwięków instrumentów muzycznych. 1. PODSTAWY TEORETYCZNE ANALIZY FALKOWEJ. LABORATORIUM AKUSTYKI MUZYCZNEJ. Ćw. nr 1. Analiza falkowa dźwięków instrumentów muzycznych. 1. PODSTAWY TEORETYCZNE ANALIZY FALKOWEJ. Transformacja falkowa (ang. wavelet falka) przeznaczona jest do analizy

Bardziej szczegółowo

INFORMATYKA W SZKOLE. Podyplomowe Studia Pedagogiczne. Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227

INFORMATYKA W SZKOLE. Podyplomowe Studia Pedagogiczne. Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 INFORMATYKA W SZKOLE Dr inż. Grażyna KRUPIŃSKA grazyna@fis.agh.edu.pl D-10 pokój 227 Podyplomowe Studia Pedagogiczne 2 Algorytmy Nazwa algorytm wywodzi się od nazwiska perskiego matematyka Muhamed ibn

Bardziej szczegółowo

Przekształcenia widmowe Transformata Fouriera. Adam Wojciechowski

Przekształcenia widmowe Transformata Fouriera. Adam Wojciechowski Przekształcenia widmowe Transformata Fouriera Adam Wojciechowski Przekształcenia widmowe Odmiana przekształceń kontekstowych, w których kontekstem jest w zasadzie cały obraz. Za pomocą transformaty Fouriera

Bardziej szczegółowo

Przygotowanie kilku wersji kodu zgodnie z wymogami wersji zadania,

Przygotowanie kilku wersji kodu zgodnie z wymogami wersji zadania, Przetwarzanie równoległe PROJEKT OMP i CUDA Temat projektu dotyczy analizy efektywności przetwarzania równoległego realizowanego przy użyciu komputera równoległego z procesorem wielordzeniowym z pamięcią

Bardziej szczegółowo

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA Wprowadzenie do programowania w środowisku CUDA Środowisko CUDA 1 Budowa procesora CPU i GPU Architektura GPU wymaga większej ilości tranzystorów na przetwarzanie danych Control ALU ALU ALU ALU Cache DRAM

Bardziej szczegółowo

Transformaty. Kodowanie transformujace

Transformaty. Kodowanie transformujace Transformaty. Kodowanie transformujace Kodowanie i kompresja informacji - Wykład 10 10 maja 2009 Szeregi Fouriera Każda funkcję okresowa f (t) o okresie T można zapisać jako f (t) = a 0 + a n cos nω 0

Bardziej szczegółowo

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

CUDA Median Filter filtr medianowy wykorzystujący bibliotekę CUDA sprawozdanie z projektu CUDA Median Filter filtr medianowy wykorzystujący bibliotekę CUDA sprawozdanie z projektu inż. Daniel Solarz Wydział Fizyki i Informatyki Stosowanej AGH 1. Cel projektu. Celem projektu było napisanie wtyczki

Bardziej szczegółowo

Rozpoznawanie obrazu. Teraz opiszemy jak działa robot.

Rozpoznawanie obrazu. Teraz opiszemy jak działa robot. Rozpoznawanie obrazu Implementujesz oprogramowanie do rozpoznawania obrazu dla robota. Za każdym razem, gdy robot robi zdjęcie kamerą, jest ono zapisywane jako czarno-biały obraz w pamięci robota. Każdy

Bardziej szczegółowo

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu. Część XIX C++ w Każda poznana do tej pory zmienna może przechowywać jedną liczbę. Jeśli zaczniemy pisać bardziej rozbudowane programy, okaże się to niewystarczające. Warto więc poznać zmienne, które mogą

Bardziej szczegółowo

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

Programowanie procesorów graficznych NVIDIA (rdzenie CUDA) Wykład nr 1 Programowanie procesorów graficznych NVIDIA (rdzenie CUDA) Wykład nr 1 Wprowadzenie Procesory graficzne GPU (Graphics Processing Units) stosowane są w kartach graficznych do przetwarzania grafiki komputerowej

Bardziej szczegółowo

BIBLIOTEKA PROGRAMU R - BIOPS. Narzędzia Informatyczne w Badaniach Naukowych Katarzyna Bernat

BIBLIOTEKA PROGRAMU R - BIOPS. Narzędzia Informatyczne w Badaniach Naukowych Katarzyna Bernat BIBLIOTEKA PROGRAMU R - BIOPS Narzędzia Informatyczne w Badaniach Naukowych Katarzyna Bernat Biblioteka biops zawiera funkcje do analizy i przetwarzania obrazów. Operacje geometryczne (obrót, przesunięcie,

Bardziej szczegółowo

Kody Tunstalla. Kodowanie arytmetyczne

Kody Tunstalla. Kodowanie arytmetyczne Kody Tunstalla. Kodowanie arytmetyczne Kodowanie i kompresja informacji - Wykład 3 8 marca 2010 Kody Tunstalla Wszystkie słowa kodowe maja ta sama długość ale jeden kod może kodować różna liczbę liter

Bardziej szczegółowo

Kodowanie i kompresja Tomasz Jurdziński Studia Wieczorowe Wykład Kody liniowe - kodowanie w oparciu o macierz parzystości

Kodowanie i kompresja Tomasz Jurdziński Studia Wieczorowe Wykład Kody liniowe - kodowanie w oparciu o macierz parzystości Kodowanie i kompresja Tomasz Jurdziński Studia Wieczorowe Wykład 13 1 Kody liniowe - kodowanie w oparciu o macierz parzystości Przykład Różne macierze parzystości dla kodu powtórzeniowego. Co wiemy z algebry

Bardziej szczegółowo

6. Algorytmy ochrony przed zagłodzeniem dla systemów Linux i Windows NT.

6. Algorytmy ochrony przed zagłodzeniem dla systemów Linux i Windows NT. WYDZIAŁ: GEOLOGII, GEOFIZYKI I OCHRONY ŚRODOWISKA KIERUNEK STUDIÓW: INFORMATYKA STOSOWANA RODZAJ STUDIÓW: STACJONARNE I STOPNIA ROK AKADEMICKI 2014/2015 WYKAZ PRZEDMIOTÓW EGZAMINACYJNYCH: I. Systemy operacyjne

Bardziej szczegółowo

Cyfrowe przetwarzanie i kompresja danych. dr inż.. Wojciech Zając

Cyfrowe przetwarzanie i kompresja danych. dr inż.. Wojciech Zając Cyfrowe przetwarzanie i kompresja danych dr inż.. Wojciech Zając Wykład 7. Standardy kompresji obrazów nieruchomych Obraz cyfrowy co to takiego? OBRAZ ANALOGOWY OBRAZ CYFROWY PRÓBKOWANY 8x8 Kompresja danych

Bardziej szczegółowo

Analiza ilościowa w przetwarzaniu równoległym

Analiza ilościowa w przetwarzaniu równoległym Komputery i Systemy Równoległe Jędrzej Ułasiewicz 1 Analiza ilościowa w przetwarzaniu równoległym 10. Analiza ilościowa w przetwarzaniu równoległym...2 10.1 Kryteria efektywności przetwarzania równoległego...2

Bardziej szczegółowo

Systemy liczbowe. 1. Przedstawić w postaci sumy wag poszczególnych cyfr liczbę rzeczywistą R = (10).

Systemy liczbowe. 1. Przedstawić w postaci sumy wag poszczególnych cyfr liczbę rzeczywistą R = (10). Wprowadzenie do inżynierii przetwarzania informacji. Ćwiczenie 1. Systemy liczbowe Cel dydaktyczny: Poznanie zasad reprezentacji liczb w systemach pozycyjnych o różnych podstawach. Kodowanie liczb dziesiętnych

Bardziej szczegółowo

przetworzonego sygnału

przetworzonego sygnału Synteza falek ortogonalnych na podstawie oceny przetworzonego sygnału Instytut Informatyki Politechnika Łódzka 28 lutego 2012 Plan prezentacji 1 Sformułowanie problemu 2 3 4 Historia przekształcenia falkowego

Bardziej szczegółowo

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0,

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0, 2 Arytmetyka Niech b = d r d r 1 d 1 d 0 będzie zapisem liczby w systemie dwójkowym Zamiana zapisu liczby b na system dziesiętny odbywa się poprzez wykonanie dodawania d r 2 r + d r 1 2 r 1 d 1 2 1 + d

Bardziej szczegółowo

Stan wysoki (H) i stan niski (L)

Stan wysoki (H) i stan niski (L) PODSTAWY Przez układy cyfrowe rozumiemy układy, w których w każdej chwili występują tylko dwa (zwykle) możliwe stany, np. tranzystor, jako element układu cyfrowego, może być albo w stanie nasycenia, albo

Bardziej szczegółowo

Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego

Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego Arytmetyka cyfrowa Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego (binarnego). Zapis binarny - to system liczenia

Bardziej szczegółowo

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

Skalowalność obliczeń równoległych. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1 Skalowalność obliczeń równoległych Krzysztof Banaś Obliczenia Wysokiej Wydajności 1 Skalowalność Przy rozważaniu wydajności przetwarzania (obliczeń, komunikacji itp.) często pojawia się pojęcie skalowalności

Bardziej szczegółowo

Definicje. Algorytm to:

Definicje. Algorytm to: Algorytmy Definicje Algorytm to: skończony ciąg operacji na obiektach, ze ściśle ustalonym porządkiem wykonania, dający możliwość realizacji zadania określonej klasy pewien ciąg czynności, który prowadzi

Bardziej szczegółowo

PAMIĘCI. Część 1. Przygotował: Ryszard Kijanka

PAMIĘCI. Część 1. Przygotował: Ryszard Kijanka PAMIĘCI Część 1 Przygotował: Ryszard Kijanka WSTĘP Pamięci półprzewodnikowe są jednym z kluczowych elementów systemów cyfrowych. Służą do przechowywania informacji w postaci cyfrowej. Liczba informacji,

Bardziej szczegółowo

Kod uzupełnień do dwóch jest najczęściej stosowanym systemem zapisu liczb ujemnych wśród systemów binarnych.

Kod uzupełnień do dwóch jest najczęściej stosowanym systemem zapisu liczb ujemnych wśród systemów binarnych. Kod uzupełnień do dwóch jest najczęściej stosowanym systemem zapisu liczb ujemnych wśród systemów binarnych. Jeśli bit znaku przyjmie wartość 0 to liczba jest dodatnia lub posiada wartość 0. Jeśli bit

Bardziej szczegółowo

Samodzielnie wykonaj następujące operacje: 13 / 2 = 30 / 5 = 73 / 15 = 15 / 23 = 13 % 2 = 30 % 5 = 73 % 15 = 15 % 23 =

Samodzielnie wykonaj następujące operacje: 13 / 2 = 30 / 5 = 73 / 15 = 15 / 23 = 13 % 2 = 30 % 5 = 73 % 15 = 15 % 23 = Systemy liczbowe Dla każdej liczby naturalnej x Î N oraz liczby naturalnej p >= 2 istnieją jednoznacznie wyznaczone: liczba n Î N oraz ciąg cyfr c 0, c 1,..., c n-1 (gdzie ck Î {0, 1,..., p - 1}) taki,

Bardziej szczegółowo

Kodowanie transformujace. Kompresja danych. Tomasz Jurdziński. Wykład 11: Transformaty i JPEG

Kodowanie transformujace. Kompresja danych. Tomasz Jurdziński. Wykład 11: Transformaty i JPEG Tomasz Wykład 11: Transformaty i JPEG Idea kodowania transformujacego Etapy kodowania 1 Wektor danych x 0,...,x N 1 przekształcamy (odwracalnie!) na wektor c 0,...,c N 1, tak aby: energia była skoncentrowana

Bardziej szczegółowo

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

Programowanie współbieżne Wykład 2. Iwona Kochańska Programowanie współbieżne Wykład 2 Iwona Kochańska Miary skalowalności algorytmu równoległego Przyspieszenie Stały rozmiar danych N T(1) - czas obliczeń dla najlepszego algorytmu sekwencyjnego T(p) - czas

Bardziej szczegółowo

Przetwornik analogowo-cyfrowy

Przetwornik analogowo-cyfrowy Przetwornik analogowo-cyfrowy Przetwornik analogowo-cyfrowy A/C (ang. A/D analog to digital; lub angielski akronim ADC - od słów: Analog to Digital Converter), to układ służący do zamiany sygnału analogowego

Bardziej szczegółowo

12. Wprowadzenie Sygnały techniki cyfrowej Systemy liczbowe. Matematyka: Elektronika:

12. Wprowadzenie Sygnały techniki cyfrowej Systemy liczbowe. Matematyka: Elektronika: PRZYPOMNIJ SOBIE! Matematyka: Dodawanie i odejmowanie "pod kreską". Elektronika: Sygnały cyfrowe. Zasadę pracy tranzystorów bipolarnych i unipolarnych. 12. Wprowadzenie 12.1. Sygnały techniki cyfrowej

Bardziej szczegółowo

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

PROGRAMOWANIE WSPÓŁCZESNYCH ARCHITEKTUR KOMPUTEROWYCH DR INŻ. KRZYSZTOF ROJEK 1 PROGRAMOWANIE WSPÓŁCZESNYCH ARCHITEKTUR KOMPUTEROWYCH DR INŻ. KRZYSZTOF ROJEK POLITECHNIKA CZĘSTOCHOWSKA 2 Trendy rozwoju współczesnych procesorów Budowa procesora CPU na przykładzie Intel Kaby Lake

Bardziej szczegółowo

Metody numeryczne Wykład 4

Metody numeryczne Wykład 4 Metody numeryczne Wykład 4 Dr inż. Michał Łanczont Instytut Elektrotechniki i Elektrotechnologii E419, tel. 4293, m.lanczont@pollub.pl, http://m.lanczont.pollub.pl Zakres wykładu Metody skończone rozwiązywania

Bardziej szczegółowo

Kodowanie informacji

Kodowanie informacji Kodowanie informacji Tomasz Wykład 4: kodowanie arytmetyczne Motywacja Podstawy i własności Liczby rzeczywiste Motywacje 1 średnia długość kodu Huffmana może odbiegać o p max + 0.086 od entropii, gdzie

Bardziej szczegółowo

Wydajność obliczeń a architektura procesorów. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1

Wydajność obliczeń a architektura procesorów. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1 Wydajność obliczeń a architektura procesorów Krzysztof Banaś Obliczenia Wysokiej Wydajności 1 Wydajność komputerów Modele wydajności-> szacowanie czasu wykonania zadania Wydajność szybkość realizacji wyznaczonych

Bardziej szczegółowo

Wprowadzenie do architektury komputerów systemy liczbowe, operacje arytmetyczne i logiczne

Wprowadzenie do architektury komputerów systemy liczbowe, operacje arytmetyczne i logiczne Wprowadzenie do architektury komputerów systemy liczbowe, operacje arytmetyczne i logiczne 1. Bit Pozycja rejestru lub komórki pamięci służąca do przedstawiania (pamiętania) cyfry w systemie (liczbowym)

Bardziej szczegółowo

Numeryczna algebra liniowa

Numeryczna algebra liniowa Numeryczna algebra liniowa Numeryczna algebra liniowa obejmuje szereg algorytmów dotyczących wektorów i macierzy, takich jak podstawowe operacje na wektorach i macierzach, a także rozwiązywanie układów

Bardziej szczegółowo

Aproksymacja funkcji a regresja symboliczna

Aproksymacja funkcji a regresja symboliczna Aproksymacja funkcji a regresja symboliczna Problem aproksymacji funkcji polega na tym, że funkcję F(x), znaną lub określoną tablicą wartości, należy zastąpić inną funkcją, f(x), zwaną funkcją aproksymującą

Bardziej szczegółowo

Transformacja Fouriera i biblioteka CUFFT 3.0

Transformacja Fouriera i biblioteka CUFFT 3.0 Transformacja Fouriera i biblioteka CUFFT 3.0 Procesory Graficzne w Zastosowaniach Obliczeniowych Karol Opara Warszawa, 14 kwietnia 2010 Transformacja Fouriera Definicje i Intuicje Transformacja z dziedziny

Bardziej szczegółowo

Budowa komputera Komputer computer computare

Budowa komputera Komputer computer computare 11. Budowa komputera Komputer (z ang. computer od łac. computare obliczać) urządzenie elektroniczne służące do przetwarzania wszelkich informacji, które da się zapisać w formie ciągu cyfr albo sygnału

Bardziej szczegółowo

Zastosowanie kompresji w kryptografii Piotr Piotrowski

Zastosowanie kompresji w kryptografii Piotr Piotrowski Zastosowanie kompresji w kryptografii Piotr Piotrowski 1 Plan prezentacji I. Wstęp II. Kryteria oceny algorytmów III. Główne klasy algorytmów IV. Przykłady algorytmów selektywnego szyfrowania V. Podsumowanie

Bardziej szczegółowo

Obliczenia iteracyjne

Obliczenia iteracyjne Lekcja Strona z Obliczenia iteracyjne Zmienne iteracyjne (wyliczeniowe) Obliczenia iteracyjne wymagają zdefiniowania specjalnej zmiennej nazywanej iteracyjną lub wyliczeniową. Zmienną iteracyjną od zwykłej

Bardziej szczegółowo

Budowa i zasada działania komputera. dr Artur Bartoszewski

Budowa i zasada działania komputera. dr Artur Bartoszewski Budowa i zasada działania komputera 1 dr Artur Bartoszewski Jednostka arytmetyczno-logiczna 2 Pojęcie systemu mikroprocesorowego Układ cyfrowy: Układy cyfrowe służą do przetwarzania informacji. Do układu

Bardziej szczegółowo

Język C zajęcia nr 11. Funkcje

Język C zajęcia nr 11. Funkcje Język C zajęcia nr 11 Funkcje W języku C idea podprogramów realizowana jest wyłącznie poprzez definiowanie i wywołanie funkcji. Każda funkcja musi być przed wywołaniem zadeklarowana. Deklaracja funkcji

Bardziej szczegółowo

Lab 9 Podstawy Programowania

Lab 9 Podstawy Programowania Lab 9 Podstawy Programowania (Kaja.Gutowska@cs.put.poznan.pl) Wszystkie kody/fragmenty kodów dostępne w osobnym pliku.txt. Materiały pomocnicze: Wskaźnik to specjalny rodzaj zmiennej, w której zapisany

Bardziej szczegółowo

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Część XXII C++ w Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Ćwiczenie 1 1. Utwórz nowy projekt w Dev C++ i zapisz go na

Bardziej szczegółowo

Metody optymalizacji soft-procesorów NIOS

Metody optymalizacji soft-procesorów NIOS POLITECHNIKA WARSZAWSKA Wydział Elektroniki i Technik Informacyjnych Instytut Telekomunikacji Zakład Podstaw Telekomunikacji Kamil Krawczyk Metody optymalizacji soft-procesorów NIOS Warszawa, 27.01.2011

Bardziej szczegółowo

SIMR 2016/2017, Analiza 2, wykład 1, Przestrzeń wektorowa

SIMR 2016/2017, Analiza 2, wykład 1, Przestrzeń wektorowa SIMR 06/07, Analiza, wykład, 07-0- Przestrzeń wektorowa Przestrzeń wektorowa (liniowa) - przestrzeń (zbiór) w której określone są działania (funkcje) dodawania elementów i mnożenia elementów przez liczbę

Bardziej szczegółowo

FFT i dyskretny splot. Aplikacje w DSP

FFT i dyskretny splot. Aplikacje w DSP i dyskretny splot. Aplikacje w DSP Marcin Jenczmyk m.jenczmyk@knm.katowice.pl Wydział Matematyki, Fizyki i Chemii 10 maja 2014 M. Jenczmyk Sesja wiosenna KNM 2014 i dyskretny splot 1 / 17 Transformata

Bardziej szczegółowo

Zastosowanie falek w przetwarzaniu obrazów

Zastosowanie falek w przetwarzaniu obrazów Informatyka, S2 sem. Letni, 2013/2014, wykład#1 Zastosowanie falek w przetwarzaniu obrazów dr inż. Paweł Forczmański Katedra Systemów Multimedialnych, Wydział Informatyki ZUT 1 / 61 Alfréd Haar Alfréd

Bardziej szczegółowo

3. Opracować program kodowania/dekodowania pliku tekstowego. Algorytm kodowania:

3. Opracować program kodowania/dekodowania pliku tekstowego. Algorytm kodowania: Zadania-7 1. Opracować program prowadzący spis pracowników firmy (max.. 50 pracowników). Każdy pracownik opisany jest za pomocą struktury zawierającej nazwisko i pensję. Program realizuje następujące polecenia:

Bardziej szczegółowo

Arytmetyka komputera. Na podstawie podręcznika Urządzenia techniki komputerowej Tomasza Marciniuka. Opracował: Kamil Kowalski klasa III TI

Arytmetyka komputera. Na podstawie podręcznika Urządzenia techniki komputerowej Tomasza Marciniuka. Opracował: Kamil Kowalski klasa III TI Arytmetyka komputera Na podstawie podręcznika Urządzenia techniki komputerowej Tomasza Marciniuka Opracował: Kamil Kowalski klasa III TI Spis treści 1. Jednostki informacyjne 2. Systemy liczbowe 2.1. System

Bardziej szczegółowo

Mathcad c.d. - Macierze, wykresy 3D, rozwiązywanie równań, pochodne i całki, animacje

Mathcad c.d. - Macierze, wykresy 3D, rozwiązywanie równań, pochodne i całki, animacje Mathcad c.d. - Macierze, wykresy 3D, rozwiązywanie równań, pochodne i całki, animacje Opracował: Zbigniew Rudnicki Powtórka z poprzedniego wykładu 2 1 Dokument, regiony, klawisze: Dokument Mathcada realizuje

Bardziej szczegółowo

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania 1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja nie ma parametru i zwraca wartość na zewnątrz. nie ma parametru i nie zwraca wartości na zewnątrz. ma parametr o nazwie void i zwraca

Bardziej szczegółowo

Wstęp do informatyki- wykład 2

Wstęp do informatyki- wykład 2 MATEMATYKA 1 Wstęp do informatyki- wykład 2 Systemy liczbowe Treści prezentowane w wykładzie zostały oparte o: S. Prata, Język C++. Szkoła programowania. Wydanie VI, Helion, 2012 www.cplusplus.com Jerzy

Bardziej szczegółowo

Przetwarzanie Sygnałów. Zastosowanie Transformaty Falkowej w nadzorowaniu

Przetwarzanie Sygnałów. Zastosowanie Transformaty Falkowej w nadzorowaniu Akademia Górniczo-Hutnicza Wydział Elektrotechniki, Automatyki, Informatyki i Inżynierii Biomedycznej Przetwarzanie Sygnałów Studia Podyplomowe, Automatyka i Robotyka Zastosowanie Transformaty Falkowej

Bardziej szczegółowo

Klasyfikacja metod kompresji

Klasyfikacja metod kompresji dr inż. Piotr Odya Klasyfikacja metod kompresji Metody bezstratne Zakodowany strumień danych po dekompresji jest identyczny z oryginalnymi danymi przed kompresją, Metody stratne W wyniku kompresji część

Bardziej szczegółowo

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6 JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 6 1 SPECYFIKATOR static Specyfikator static: Specyfikator ten powoduje, że zmienna lokalna definiowana w obrębie danej funkcji nie jest niszczona

Bardziej szczegółowo