Praca dyplomowa inżynierska Stanisław Ogórkis -...

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

Transcript of Praca dyplomowa inżynierska Stanisław Ogórkis -...

Page 1: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Politechnika Warszawska

Wydział Elektroniki i Technik Informacyjnych

Instytut Informatyki

Rok akademicki 2010/2011

Praca dyplomowa inżynierska

Stanisław Ogórkis

Kompresja falkowa w środowiskuNVIDIA CUDA

Opiekun pracy:

mgr inż. Julian Myrcha

Ocena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Podpis Przewodniczącego

Komisji Egzaminu Dyplomowego

Page 2: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 Su-

wał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 Informacyj-

nych 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Page 3: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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. Zaprezento-

wane są algorytmy związane z transformatą falkową, kwantyzacją i kodowaniem arytme-

tycznym.

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 com-

pressor. 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.

Page 4: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Spis treści

1 Wstęp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.1 Zdefiniowanie problemu . . . . . . . . . . . . . . . . . . . . . . . . 3

1.2 Cele pracy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.3 Zawartość pracy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Transformata falkowa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.1 Informacje ogólne . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2 Funkcja falkowa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3 Realizacja dyskretnej transformaty falkowej przy użyciu filtrów . . . 6

2.4 Przykład obliczenia transformaty i transformaty odwrotnej . . . . . 7

2.5 Współczynniki filtrów falkowych . . . . . . . . . . . . . . . . . . . . 9

2.6 Transformata sygnałów wielowymiarowych . . . . . . . . . . . . . . 11

2.7 Algorytm konwolucji . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Metody kwantyzacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.1 Skalarna kwantyzacja równomierna . . . . . . . . . . . . . . . . . . 14

3.2 Skalarna kwantyzacja nierównomierna . . . . . . . . . . . . . . . . 14

3.3 Skalarna kwantyzacja równomierna z rozszerzonym przedziałem ze-

rowym . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4 Kodowanie arytmetyczne . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.1 Kodowanie arytmetyczne oparte o arytmetykę rzeczywistoliczbową . 17

4.2 Przykład . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4.3 Kodowanie arytmetyczne oparte o arytmetykę całkowitoliczbową . . 19

4.4 Koder adaptacyjny . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5 Technologia NVIDIA CUDA . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.1 Efektywność obliczeniowa procesorów graficznych . . . . . . . . . . 22

5.2 Model programowania . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.3 Funkcje kerneli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.4 Hierarchia wątków . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

5.5 Hierarchia pamięci . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

6 Opis proponowanego rozwiązania . . . . . . . . . . . . . . . . . . . . . . . 29

6.1 Wymagania dotyczące aplikacji . . . . . . . . . . . . . . . . . . . . 29

6.2 Funkcje aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

1

Page 5: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

6.3 Architektura rozwiązania . . . . . . . . . . . . . . . . . . . . . . . . 31

7 Implementacja projektu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

7.1 Platforma sprzętowa . . . . . . . . . . . . . . . . . . . . . . . . . . 39

7.2 Narzędzia i biblioteki . . . . . . . . . . . . . . . . . . . . . . . . . . 40

7.3 Algorytm obliczania transformaty falkowej na procesorze GPU . . . 41

7.4 Mechanizmy pomiaru czasu . . . . . . . . . . . . . . . . . . . . . . 44

8 Weryfikacja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

8.1 Zbiór testowy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

8.2 Precyzja obliczeń . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

8.3 Efektywność kompresji . . . . . . . . . . . . . . . . . . . . . . . . . 48

8.4 Szybkość działania . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

9 Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

2

Page 6: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

1 Wstęp

1.1 Zdefiniowanie problemu

Uzyskanie możliwie najkrótszej reprezentacji danych jest głównym kryterium stoso-

wanym 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żliwia-

ją 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ą jednako-

wego 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ą trans-

formaty, 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. Kwan-

tyzacja 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ę wyko-

rzystują 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 Stephane 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 separo-

walność 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ż dwu-

wymiarowych wymaga znacznych nakładów obliczeniowych. Przy ciągłym rozwoju gra-

fiki 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 obli-

czeń (GPU Computing). Kompresja falkowa bardzo dobrze nadaje się do implementacji

na GPU dzięki możliwości zrównoleglenia obliczeń.

3

Page 7: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 im-

plementacji 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. Przedsta-

wił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 roz-

dziale 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

Page 8: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

2 Transformata falkowa

2.1 Informacje ogólne

Transformaty wykorzystywane w przetwarzaniu sygnałów wykorzystują iloczyn ska-

larny 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 po-

stać:

X(a, b) =1√a

∫ ∞−∞

x(t)ψ∗(t− ba

)dt (1)

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

∫ ∞−∞

1a2X(a, b)

1√|a|ψ∼

(t− ba

)dbda (2)

gdzie ψ∼ jest funkcją odwrotną do ψ∗.

2.2 Funkcja falkowa

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

Page 9: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

2.3 Realizacja dyskretnej transformaty falkowej przy użyciu fil-

trów

Na potrzeby cyfrowego przetwarzania sygnałów wykorzystywana jest dyskretna trans-

formata 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 przetwa-

rzania 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 funk-

cji falkowej należy wyliczyć współczynniki filtru górno i dolnoprzepustowego (oznaczane

odpowiednio H0 i H1) oraz filtrów syntezy (F0 i F1). Sygnał poddawany jest filtracji i

uzyskujemy na wyjściu filtra dolno przepustowego składowe niskoczęstotliwościowe (yL),

a na wyjściu filtru górno przepustowego składowe wysokoczęstotliwościowe (yH).

yL[n] = (x ∗H1)[n]

yH [n] = (x ∗H0)[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 wsta-

wienie zer w miejsca poprzednio usuniętych wartości (oznaczane przez ↑ 2). Jako że prób-

ki 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 F0 i F1 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

Page 10: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

wzorów jakie mają spełniać zestawy filtrów H0H1F0F1, aby sygnał po przejściu przez nie

został identycznie zrekonstruowany. Mają one postać:

H0(z)F0(z) +H1(z)F1(z) = 2

H0(−z)F0(z) +H1(−z)F1(z) = 0

Wyznaczając odpowiednie wartości współczynników filtrów jesteśmy w stanie efektyw-

nie implementować algorytmy transformaty falkowej. Dekompozycja sygnału może być

kontynuowana w podpaśmie najniżej częstotliwości. Na rysunku 2 przedstawiono trzy-

poziomowy 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 po-

krywają całe spektrum częstotliwości. Nie tracimy więc żadnej informacji w wyniku wy-

konania tego przekształcenia. Współczynniki zwrócone przez filtr górnoprzepustowy na-

zywamy 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 wy-

korzystaniu falki Haara. Transformacie zostanie poddany ośmioelementowy ciąg liczbowy.

Wykonana zostanie trzypoziomowa dekompozycja sygnału wejściowego. Najpierw przed-

stawię postać falki Haara.

7

Page 11: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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ć:

ψ(x) =

1 dla 0 ¬ t < 1/2

−1 dla 12 ¬ t < 1

0 dla pozostałych t

a funkcję skalującą ϕ(t):

ϕ(t) =

0 dla 0 ¬ t < 1

1 dla pozostałych t

Rysunek 3: Falka Haara

Obliczenie współczynników

Załóżmy, że dany mamy ośmio elementowy ciąg:

4 2 5 5 7 5 1 3

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

Page 12: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

3 5 6 2

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 zrekonstru-

ować dwie wartości wejściowe. Nie tracimy zatem w wyniku tego przekształcenia żadnej

informacji. Współczynniki detali wynoszą:

1 0 1 −1

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 [3 5 6 2] [1 0 1 −1]

2 [4 4 ] [−1 2]

3 [4] [0]

W przedstawiony sposób obliczyliśmy współczynniki transformaty falkowej przy wyko-

rzystaniu banku filtrów. Rekonstrukcja wejściowego ciągu polega na rekursywnym doda-

waniu i odejmowaniu współczynników detali do współczynników uśrednionych na poszcze-

gólnych poziomach dekompozycji. Ostatecznie obliczone współczynniki mają wartości:

4 0 −1 2 1 0 1 −1

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 falko-

we 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

Page 13: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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].

Indekswspółczynnika

haarlow haarhigh daub4low daub4high daub6low daub6high

0 1 1 0.6830127 -0.830127 0.47046721 0.049817501 1 -1 1.1830127 -0.3169873 1.14111692 0.120832212 0.3169873 1.1830127 0.65036500 -0.190934423 -0.1830127 -0.6830127 -0.19093442 -0.65036504 -0.12083221 1.141116925 0.0498175 -0.47046721

Tabela 1: Współczynniki filtrów falek ortogonalnych Haar, Daub4 i Daub6

Indekswspółczynnika

analysislow analysishigh synthesislow synthesishigh

-4 0.026748757411 0 0 0.026748757411-3 -0.016864118443 0.091271763114 -0.091271763114 0.016864118443-2 -0.078223266529 -0.057543526229 -0.057543526229 -0.078223266529-1 0.266864118443 -0.591271763114 0.591271763114 -0.2668641184430 0.602949018236 1.11508705 1.11508705 0.6029490182361 0.266864118443 -0.591271763114 0.591271763114 -0.2668641184432 -0.078223266529 -0.057543526229 -0.057543526229 -0.0782232665293 -0.016864118443 0.091271763114 -0.091271763114 0.0168641184434 0.026748757411 0 0 0.026748757411

Tabela 2: Współczynniki filtrów falki biortogonalnej CDF97

10

Page 14: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Indekswspółczynnika

analysislow analysishigh synthesislow synthesishigh

-4 8.28284032 0 0 -12.28284032-3 4.482956738 -19.543487188 -19.543487188 -8.482956738-2 -4.007083083 9.06053045 -13.06053045 2.007083083-1 9.258873244 10.364926289 10.364926289 9.2588732440 22.178753243 -22.433261231 20.433261231 -24.1787532431 9.258873244 10.364926289 10.364926289 9.2588732442 -4.007083083 9.06053045 -13.06053045 2.0070830833 -8.482956738 -19.543487188 -19.543487188 -8.4829567384 8.28284032 0 0 -12.28284032

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 algo-

rytm dekompozycji Mallata, który dzieli obraz na podpasma, w których znajdują się odpo-

wiednio 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 ko-

lejnym kroku wykonujemy analogiczne działanie na wektorach kolumn. Wynik działania

takiej procedury pokazany jest na rysunku 5. Dekompozycję można kontynuować w pod-

paśmie A, aby jeszcze zmniejszyć ilość współczynników pasma niskoczęstotliwościowego.

11

Page 15: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Rysunek 5: Schematyczny sposób działania dekompozycji wielorozdzielczej obrazu: a)obraz orginalny; b) obraz poddany dekompozycji jednopoziomowej c) przykład działaniana 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 fil-

tró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ć:

yL[n] = (x ∗H1)[n] =+∞∑k=−∞

= x[k]H1[2n− k]

yH [n] = (x ∗H0)[n] =+∞∑k=−∞

= x[k]H0[2n− k]

(5)

Zastosowano tutaj od razu operator ↓ 2 wyrzucania co drugiej próbki.1 Takie zastoso-

wanie algorytmu konwolucji doprowadza jednak do kilku problemów. Przede wszystkim

1czynnik H[n− k] został zamieniony na H[2n− k]

12

Page 16: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 wyko-

naniu 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] =

x[n] dla 0 ­ n < 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 ograni-

czone 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

2D. Dodatkowo na granicy sygnału pojawia się nieciągłość, która powoduje większą war-

tość 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 jed-

nak bardziej skomplikowany i zależny od zastosowanych banków filtrów. Szczegółowy opis

działania rozszerzania symetrycznego znajduje się w pracy [3].

13

Page 17: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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łce-

nia 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 =1n

∑i

(x(i)− x∗(i))2 (6)

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ółczyn-

nikó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 (fmin, fmax). Cały zakres

jest dzielony na L równych przedziałów o długości Q nazywanych przedziałem kwantyzacji

(rysunek 7):

Q = (fmax − fmin)/L (7)

Wartość leżąca w danym przedziale kwantyzacji jest odwzorowywana na środkową

wartość tego przedziału. W wyniku kwantyzacji uzyskujemy indeks przedziału kwantyza-

cji:

Qi(f) = bf − fminQ

c (8)

Aby przeprowadzić dekwantyzację należy znać wartości fmin i fmax oraz indeksy prze-

działów kwantyzacji dla poszczególnych symboli:

Q(f) = Qi(f)Q+Q/2 + fmin (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

Page 18: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 bi-

tów, więc nie jest stosowane w kompresji. Wykorzystywane są specjalne modele, które

pozwalają na nieliniowe odwzorowanie przedziałów kwantyzacji bez wysłania dodatko-

wych informacji.

3.3 Skalarna kwantyzacja równomierna z rozszerzonym prze-

działem zerowym

Kwantyzacja równomierna z rozszerzonym przedziałem zerowym jest szczególnie efek-

tywna 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

Page 19: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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]). Oznacz-

my przez ∆ przedział kwantyzacji dla kwantyzatora równomiernego. Wówczas wartość

skwantyzowana q dla elementu f wynosi:

q =

0 dla |f | ¬ −nz∆

sign(f)b |f |+nz∆∆ c dla |f | ­ −nz∆(10)

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:

f =

0 dla q = 0

sign(q)(|q| − nz + 0.5)∆ dla q 6= 0(11)

Rysunek 9: Podział na przedziały kwantyzacji w kwantyzatorze równomiernym z rozsze-rzonym przedziałem zerowym

16

Page 20: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

4 Kodowanie arytmetyczne

Uzyskany w wyniku kwantyzacji strumień symboli kodowany jest koderem entropij-

nym. Metoda Huffmana wykorzystuje do zakodowania symbolu całkowitą liczbę bitów.

Takie działanie powoduje jednak, że metoda ta jest nieoptymalna. Przytaczając zamiesz-

czony 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ę rzeczywisto-

liczbową

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 ko-

dowego wraz z kodowaniem kolejnych symboli. Ostatecznie liczbą kodową przekazywaną

do dekodera jest dowolna liczba ułamkowa wybrana z przedziału kodowego po zakodowa-

niu 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ępo-

wania 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 prze-

działu kodowego korzystając z zależności:

range = high − low ;

high = low + range ∗ high range ( symbol ) ;

low = low + range ∗ low range ( symbol ) ;

17

Page 21: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 praw-

dopodobień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 ) ) /

( h igh range ( symbol ) − low range ( symbol ) ) ;

4. Jeśli nie odczytano wszystkich symboli powrót do punktu 3.

4.2 Przykład

Załóżmy, że mamy do czynienia z czteroelementowym alfabetem a, b, c, d o prawdopo-

dobień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 0.5 0.0 ¬ p < 0.5

b 0.2 0.5 ¬ p < 0.7

c 0.2 0.7 ¬ p < 0.9

d 0.1 0.9 ¬ 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 poszcze-

gólnych symboli przykładowego ciągu wejściowego a, c, a, a, b, a, d, b.

18

Page 22: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

symbol dolny przedział górny przedział

0.0 1.0

a 0.0 0.5

c 0.35 0.45

a 0.35 0.4

a 0.35 0.375

b 0.3625 0.3675

a 0.3625 0.2650

d 0.36475 0.3650

b 0.364875 0.364925

Po zakodowaniu wybieramy liczbę kodową z końcowego zakresu [0.364875, 0.364925).

Przyjmijmy więc, że będzie to liczba 0.36488. Liczba ta wraz z informacją o prawdopodo-

bień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 0.36488 0.0 0.5

c 0.72976 0.7 0.9

a 0.1488 0.0 0.5

a 0.2976 0.0 0.5

b 0.5952 0.5 0.7

a 0.476 0.0 0.5

d 0.952 0.9 1.0

b 0.52 0.5 0.7

STOP 0.1 - -

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 prawdopodo-

bień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łkowito-

liczbową

Przedstawiony wcześniej schemat kodowania arytmetycznego opierał się na arytmetyce

rzeczywistoliczbowej. Nie da go się jednak zrealizować w praktycznych implementacjach

19

Page 23: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

ze względu na ograniczoną długość rejestrów procesorów. Po zakodowaniu zaledwie kil-

kunastu 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. Bi-

ty 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łkowitoliczbo-

wych, należy przyjąć że dolną granicę 0.0000 reprezentują wszystkie bity ustawione na

zero, a górna granicę 0.9999 reprezentują wszystkie bity ustawione na jeden. Przez wszyst-

kie 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 1001. Teraz w miarę procesu kodowania może dojść do sytuacji gdy po za-

kodowaniu kolejnego symbolu wartości te będą wynosić odpowiednio 0111 i 1000. W tym

momencie najbardziej znaczące bity będą różne, uniemożliwiając wysunięcie. Rozwiąza-

niem 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łącza-

ją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

Page 24: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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ść poszcze-

gó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, dopa-

sowują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 do-

stosuje 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. Ta-

kie rozwiązanie pozwala uzyskać w większości przypadków lepszy stopień kompresji niż

rozwiązanie z modelem statycznym.

21

Page 25: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

5 Technologia NVIDIA CUDA

W tym rozdziale zostały przedstawione podstawy technologii NVIDIA CUDA (Compu-

te Unified Device Architecture). Szczególny nacisk został położony na elementy wykorzy-

stane przy implementacji. Rozdział został przygotowany w oparciu o oficjalną dokumen-

tację [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 wy-

ewoluował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 po-

siadają 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 po-jedynczej precyzji [14]

22

Page 26: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 architek-

turze obu rozwiązań (rysunek 11). Procesor CPU jest przystosowany do sekwencyjnego

wykonywania instrukcji. Istnieją w nim mechanizmy, które sprawiają, że instrukcje we-

wnątrz procesora wykonywane są poza kolejnością mimo wrażenia sekwencyjnego wyko-

nania (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 ja-

koś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 wykona-

nia. 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 - stre-

aming 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ć pa-

mięcią urządzenia (device memory), a zwykłą pamięć RAM pamięcią hosta (host memo-

ry). Szczegóły dotyczące architektury sprzętowej kart wspierających technologię CUDA

23

Page 27: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

można znaleźć w książce [5]. W dalszej części przedstawię abstrakcje modelu programowa-

nia 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 proceso-

rem, 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ówno-

czesne 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 ko-

du 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 zdefinio-

wać 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 kwadra-

tu 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 wbu-

dowanej 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 ( f loat ∗ data ) {int index = threadIdx . x ;

data [ index ] = data [ index ]∗ data [ index ] ;

}

int main ( ) {. . .

24

Page 28: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

// 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 zmien-

nej 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 ogra-

niczonej 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

Page 29: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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, nato-

miast 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 ( f loat ∗ 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 chce-

my 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 global-

nej 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 standar-

dowej 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 ( ) {f loat ∗ hostMemory ;

26

Page 30: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

. . .

f loat ∗ deviceMemory ;

cudaMalloc ( ( void ∗∗) deviceMemory , N ∗ s i z e ( f loat ) ) ;

cudaMemcpy( deviceMemory , hostMemory , N ∗ s i z e ( f loat ) ,

cudaMemcpyHostToDevice ) ;

. . .

square<<<blockNum , THREADS PER BLOCK>>>(deviceMemory ) ;

cudaMemcpy( hostMemory , deviceMemory , N ∗ s i z e ( f loat ) ,

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 (glo-

bal 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 naj-

lepszą 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

Page 31: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 - device

• pamięć stałych - 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

Page 32: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

6 Opis proponowanego rozwiązania

W tym rozdziale przedstawiony jest opis stworzonego przeze mnie narzędzia do kom-

presji 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ę wyma-

gania 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 se-

kwencji 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ć wbudo-

wane 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ęto-

wych.

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 ob-

razó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

2Wwiększości prac z dziedziny kompresji stratnej można, np. znaleźć wyniki dla standardowego obrazutestowego ”Lena”.

29

Page 33: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

obliczania transformaty falkowej, obraz musi mieć wymiary będące wielokrotnością

liczby 2d, gdzie d to liczba poziomów dekompozycji.

Kompresja sekwencji wideo

Aplikacja umożliwia kompresję sekwencji wideo. Wymagania dotyczące liczby kolo-

ró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 gra-

ficznej.

Wyświetlanie czasu wykonania poszczególnych części programu

W aplikację wbudowane są mechanizmy liczące czas wykonania poszczególnych kro-

kó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. Aplika-

cja nie obsługuje parametryzacji poprzez żądaną jakość obrazu zrekonstruowanego.

Określenie innych parametrów

Przekazując odpowiednie argumenty wywołania aplikacja przy kodowaniu pozwa-

la na wybór algorytmów wykorzystywanych w poszczególnych krokach kompresji.

Informacje te są zapisywane w zakodowanym pliku na potrzeby dekodera. Parame-

tryzowane 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ówno-

mierny z rozszerzonym przedziałem zerowym)

30

Page 34: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

6.3 Architektura rozwiązania

Zaimplementowany przeze mnie kompresor opiera się na standardowym schemacie

transformacyjnej kompresji stratnej. Na rysunku 14 znajduje się schemat kompresji ob-

razó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 ory-

ginalny musi być odpowiednio przechowywany, aby wykonanie na karcie graficznej było

efektywne. Ważne jest, aby kanały kolorowego obrazu były przetwarzane oddzielnie. Wy-

nika 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

Page 35: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 da-

nej 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 kilkupozio-

mowej 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 wiado-

mo 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 CbCr, gdzie

Y to jasność, a Cb i Cr to składowe opisujące barwę. Poniżej znajdują się wykorzystane

wzory transformacyjne.

Y

Cb

Cr

=

0

128

128

+

0.299 0.587 0.114

−0.169 −0.331 0.500

0.500 −0.419 −0.081

∗R

G

B

32

Page 36: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

R

G

B

=

1.000 0.000 1.400

1.000 −0.343 −0.711

1.000 1.765 0.000

Y

(Cb − 128)

(Cr − 128)

Algorytm obliczania transformaty kolorów łatwo daje się zrównoleglić i zaimplemen-

tować 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 CbCr 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 falko-

wa. 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 pro-

cesorze 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 iz przesunięciem równym jeden

Obliczenie splotu wejściowego ciągu x z filtrem h, można zaimplementować przy uży-

ciu 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 pe-

riodyczne 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

Page 37: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 wyko-

rzystać 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

Page 38: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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ójwy-

miarowej 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 dekom-

pozycji zmniejszamy jego dynamikę w taki sposób, aby skutecznie poddawał się kompresji

koderem arytmetycznym. Wybór liczby poziomów dekompozycji realizuje algorytm opty-

malizacji R-D (rate-distortion).

Każde z podpasm jest kwantyzowane przy użyciu innej liczby poziomów dekompozy-

cji. 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 2b, gdzie b to ilość bitów przeznaczonych na dany współczynnik.

W wykonanym koderze zaimplementowałem dwa kwantyzatory: kwantyzator równo-

mierny i kwantyzator równomierny z rozszerzonym przedziałem zerowym. W przypadku

kwantyzatora z rozszerzonym przedziałem zerowym sygnał jest uznawany za symetryczny.

35

Page 39: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Oznacza to, że jego amplituda nie wyraża się poprzez różnicę między największym i naj-

mniejszym 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 bezstrat-

nego realizuje adaptacyjny koder arytmetyczny. Model statystyczny jest inicjalizowany

równomiernie, tj. każdy symbol uzyskuje to samo prawdopodobieństwo. Wraz z kodowa-

niem 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ęsto-

tliwoś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 pew-

nym 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 przesu-

nię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 kwanty-

zatorów.

Optymalizacja R-D

W przedstawionym do tej pory schemacie kompresji brakuje informacji o sposobie wybo-

ru liczby poziomów dekompozycji. Kompresor posiada parametr określający żądany po-

ziom 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

Page 40: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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ę trud-

niejszy. 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 po-

zwala uzyskać niski koszt bitowy przy niewielkich zniekształceniach.

Na potrzeby mojego kodera zaadaptowałem algorytm R-D z biblioteki Wavelet Ima-

ge Compression Construction Kit,3 który opiera się na artykule [20]. Korzysta on z po-

wszechnie 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 przygoto-

wać krzywe R-D. Miarą zniekształceń D jest przedstawiony wcześniej błąd średniokwa-

dratowy. 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 aryt-

metycznym 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.

3http://www.geoffdavis.net/dartmouth/wavelet/wavelet.html

37

Page 41: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Dekompresja

Skompresowany plik zawiera w sobie nagłówek określający wszystkie niezbędne do wyko-

nania dekompresji dane. Są to między innymi wymiary, liczba kanałów, liczba poziomów

dekompozycji, zastosowana funkcja falkowa, kwantyzator oraz koder arytmetyczny. Do-

datkowo 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 aryt-

metycznym. 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 fal-

kowe do pierwotnej postaci. Następnie współczynniki falkowe są poddawane odwrotnej

transformacie falkowej, która jest wykonywana analogicznie do zwykłej transformaty. Je-

dyną 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

Page 42: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

7 Implementacja projektu

W tym rozdziale przedstawiony jest opis implementacji projektu. Najpierw opiszę wy-

korzystywaną platformę sprzętową, niezbędne narzędzia oraz biblioteki. Następnie przed-

stawię 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.1Liczba multiprocesorów (MP) 16Liczba rdzeni w multiprocesorze (SP) 8Łączna liczba rdzeni 128Taktowanie zegara 1.46GHzŁączna ilość pamięci globalnej 1073020928 bajtówIlość pamięci współdzielonej na rdzeń 65535 bajtówLiczba rejestrów na rdzeń 8192Maksymalna liczba wątków na blok 512Maksymalna wielkość każdego z wymiarów w bloku 512 x 512 x 64Maksymalna wielkość każdego z wymiarów w kracie 65535 x 65535 x 1* Compute capability określa możliwości obliczeniowe procesora graficznego. Głów-

ny numer rewizji mówi o architekturze procesora, natomiast numer podrewizjiokreśla stopniowo rozwijane rozszerzenia w ramach tej samej architektury. Szcze-góły można znaleźć w dodatku G dokumentacji [14].

Komputer pracował pod kontrolą systemu Ubuntu Linux 10.10 64bit z jądrem w wersji

2.6.35.28. Wersja sterowników NVIDIA to 270.35.

39

Page 43: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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ść. Wy-

korzystał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 pu-

blicznie dostępnym repozytorium pod adresem: http://code.google.com/p/

wavelet-compressor/.

Poniżej znajdują się użyte biblioteki oraz zaadaptowany kod wraz z opisem ich wyko-

rzystania w zaimplementowanym projekcie:

OpenCV

Biblioteka OpenCV (Open Source Computer Vision) została wykorzystana do od-

czytu 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/dekodo-

wanie pojedynczych symboli.

40

Page 44: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 sy-

gnał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 ooś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ę korzy-

stają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 prze-

sunię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ółdzie-lonej

41

Page 45: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 pa-

mięć 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 wykonuje-

my 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ól-

nych kerneli. Każdy z nich ładuje najpierw dane w ramach bloku do pamięci współdzie-

lonej. 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 transformatyfalkowej obrazu

Po załadowaniu danych do pamięci współdzielonej, możemy zastosować algorytm kon-

wolucji 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 wyma-

gane 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ąt-

kó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 zapi-

sywany w pamięci globalnej przeznaczonej na wynik.

42

Page 46: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 iwysokich 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ę licz-

bę poziomów dekompozycji. Poniżej umieściłem kod wywoływany przy obliczaniu trans-

formaty 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 o f 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 o f 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 = ( currHe ight +1) / 2 ;

}

43

Page 47: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

7.4 Mechanizmy pomiaru czasu

Aplikacja posiada wbudowane w siebie mechanizmy pomiaru czasu wykonania poszcze-

gó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ń (cu-

daEventCreate) i zarejestrowanie czasu (cudaEventRecord) poprzez znacznik czasu. Syn-

chronizacja 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 kom-

presji. 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 CPUi GPU

44

Page 48: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Rysunek 28: Kroki algorytmu dekompresji poddane pomiarowi czasu dla implementacjiCPU i GPU

Analogiczny pomiar czasu działania jest zaimplementowany przy algorytmie dekom-

presji (rysunek 28). Dekodowanie arytmetyczne oraz dekwantyzacja została uwzględniona

razem. Zdekodowane koderem arytmetycznym symbole są od razu poddawane dekwanty-

zacji. 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 wykona-

niem 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

Page 49: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 zmie-

rzono czas wykonania dla implementacji na procesorze CPU i GPU. Wykorzystano wbudo-

wane 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 pod-

rozdziale 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

Page 50: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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

Page 51: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 zmienno-

przecinkowe 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. Dys-

kretna transformata falkowa jest stabilna numerycznie i niewielkie niedokładności nie

wpływają na uzyskane wyniki.

Liczba poziomówdekompozycji

Wymiary Całkowity błąd Błąd na symbol

DWT 1D 16 16777216 250.073 1.49 ∗ 10−5

DWT 2D 8 1024 x 1024 18.157 1.73 ∗ 10−5

DWT 3D 5 512 x 512 x 64 306.206 1.83 ∗ 10−5

IDWT 1D 16 16777216 213.801 1.73 ∗ 10−5

IDWT 2D 8 1024 x 1024 102.353 9.76 ∗ 10−5

IDWT 3D 5 512 x 512 x 64 278.142 1.81 ∗ 10−5

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 (Pe-

ak 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ę logaryt-

miczną, 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

Page 52: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Wzór opisujący PSNR ma następującą postać:

PSNR = 10 log10

(MAX2

MSE

)= 20 log10

(MAX√MSE

)(12)

Dla obrazów barwnych miara PSNR jest również obliczona dla każdego z kanałów osob-

no. 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 wy-

konanych przeze mnie testach aplikacji ograniczyłem się do najczęściej wykorzystywanej

miary PSNR.

W koder wbudowane są mechanizmy pomiaru powstałych w wyniku kompresji znie-

kształceń, według miary PSNR. Liczba bitów jest obliczana przez pomiar długości po-

wstał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 kwantyza-

torów: kwantyzatora równomiernego (UTQ) i kwantyzatora równomiernego z rozszerzo-

nym 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

Page 53: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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.

Poziomydekomp.

Lena CrysisUzyskanystopień

PSNRUzyskanystopień

PSNR PSNR-CY PSNR-Cb PSNR-Cr

1 37.75 16.636 32.286 30.161 29.899 37.571 36.0292 32.05 29.128 32.173 33.318 35.110 42.000 43.6763 32.45 31.176 32.068 43.761 43.816 51.412 53.2874 32.24 31.529 32.072 31.437 30.848 40.880 47.3255 32.00 31.544 32.112 30.086 30.317 40.213 46.7536 32.00 31.5447 32.02 31.5418 32.04 31.537

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 przy-

najmniej 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 Cb i Cr dostają po 0.1 budżetu bitów. Wyższa jakość kompresji

dla kanału z chrominancją wynika z cech zastosowanej transformaty kolorów.

4Inne obrazy mogą mieć inną wartość optymalną jednak będzie ona blisko tej wartości.

50

Page 54: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Kolejną zbadaną przeze mnie kwestią były wybrane filtry falkowe. W tabeli 7 przed-

stawione 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 antonini2 47.628 48.401 48.985 49.9834 37.568 39.259 40.666 40.6668 30.647 32.642 34.584 34.58416 25.854 28.278 29.801 29.80132 23.907 24.766 25.291 25.291

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

Page 55: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Stopień kompresji lena lena gray barbara pw globe moon

4

PSNR 45.651 42.357 40.666 49.148 51.270 50.524PSNR-Y 45.991 49.032 51.348 50.011PSNR-Cb 40.981 51.721 53.243 51.885PSNR-Cr 41.657 51.733 55.499 52.700

8

PSNR 42.582 36.557 34.583 44.483 49.085 49.000PSNR-Y 42.469 44.463 49.256 48.756PSNR-Cb 39.724 49.157 50.525 49.335PSNR-Cr 39.878 49.416 55.100 51.537

16

PSNR 38.593 33.929 29.801 37.695 41.553 43.416PSNR-Y 38.005 37.691 41.621 43.380PSNR-Cb 38.506 45.975 47.903 46.437PSNR-Cr 38.503 46.223 53.545 48.910

32

PSNR 35.693 31.544 25.291 32.477 36.036 39.483PSNR-Y 35.096 32.467 36.070 39.480PSNR-Cb 36.585 42.288 45.507 44.390PSNR-Cr 36.350 42.516 51.835 46.851

64

PSNR 32.331 29.317 23.201 28.851 32.550 36.723PSNR-Y 31.852 28.828 32.569 36.723PSNR-Cb 32.785 38.543 43.448 42.499PSNR-Cr 33.808 38.921 50.156 44.726

128

PSNR 29.104 26.815 21.103 25.827 30.076 34.055PSNR-Y 29.032 25.749 30.089 33.990PSNR-Cb 28.193 32.673 41.294 41.374PSNR-Cr 32.105 33.430 48.129 42.932

Tabela 8: Wyniki testów kompresji obrazów dla stopni 4, 8, 16, 32, 64 i 128 według miaryPSNR. PSNR dla obrazów barwnych został obliczony po przekształceniu na przestrzeńbarw Y CbCr, a także po przekształceniu na obraz monochromatyczny.

Stopień kompresji crysis 512x256

32

PSNR 42.677PSNR-Y 42.746PSNR-Cb 50.285PSNR-Cr 52.701

64

PSNR 38.630PSNR-Y 38.640PSNR-Cb 47.520PSNR-Cr 49.905

128

PSNR 34.721PSNR-Y 34.701PSNR-Cb 44.127PSNR-Cr 47.426

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 CbCr, a także po przekształceniu na sekwencję obrazów monochromatyczną.

52

Page 56: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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/dekom-

presji. 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. Szcze-

gół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

Page 57: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 opty-

malizacji 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śpiesze-

nie transformaty odwrotnej skutkuje ponad trzykrotnym przyśpieszeniem czasu działania

(rysunki 35 i 36).

Implementacja transformaty kolorów na procesorze GPU jest średnio kilkunastokrot-

nie 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 prze-

twarzania 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

Page 58: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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 se-

kwencji 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ęci5 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.

5dostęp po kolejnych elementach w pamięci ma miejsce przy transformacie po wierszach

55

Page 59: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

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

Page 60: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

512x512 1024x1024 2048x2048 4096x4096OpenCV open 0,005083 0,031146 0,097367 0,399815Transformata kolorów 0,002358 0,009395 0,036423 0,147462Transformata falkowa 0,130907 0,702710 2,813774 13,048168Linearyzacja 0,002362 0,006939 0,026502 0,095985Optymalizacja RD 0,326178 1,494638 5,031271 21,891127Kwantyzacja i kodowanie arytm. 0,025705 0,102173 0,405921 1,642238RAZEM 0,492593 2,347001 8,411258 37,224795

Tabela 10: Czas działania dla kompresji obrazów CPU w sekundach

512x512 1024x1024 2048x2048 4096x4096OpenCV open 0,005095 0,031177 0,097305 0,399116CUDA malloc 0,000512 0,000488 0,000293 0,000385CUDA host → device 0,018101 0,004106 0,017445 0,074997CUDA transformata kolorów 0,000148 0,000600 0,002196 0,008890CUDA transformata falkowa 0,013011 0,057505 0,337600 1,556905CUDA device → host 0,002468 0,008503 0,028768 0,123334Linearyzacja 0,001890 0,007802 0,027649 0,105700Optymalizacja RD 0,327318 1,498222 5,062164 21,894482Kwantyzacja i kodowanie arytm. 0,025596 0,101571 0,403725 1,631859RAZEM 0,394139 1,709974 5,977145 25,795668

Tabela 11: Czas działania dla kompresji obrazów CUDA w sekundach

512x512 1024x1024 2048x2048 4096x4096Dekodowanie i dekwantyzacja 0,0391400 0,146900 0,588237 2,315925Transformata kolorów 0,001748 0,006974 0,029906 0,119898Transformata falkowa 0,197179 1,000924 4,080403 17,531343Delinearyzacja 0,001935 0,006971 0,026498 0,099524OpenCV save 0,028433 0,164328 0,685740 2,983716RAZEM 0,268435 1,326097 5,410784 23,050406

Tabela 12: Czas działania dla dekompresji obrazów CPU w sekundach

512x512 1024x1024 2048x2048 4096x4096OpenCV save 0,036930 0,167261 0,665624 2,99187Delinearyzacja 0,001438 0,006763 0,026201 0,099930Dekodowanie i dekwantyzacja 0,039090 0,147483 0,587026 2,304214CUDA malloc 0,000504 0,000457 0,000102 0,000699CUDA host → device 0,001731 0,004969 0,015638 0,061258CUDA transformata kolorów 0,000280 0,000620 0,000207 0,000788CUDA transformata falkowa 0,012298 0,042797 0,231374 1,552105CUDA device → host 0,004244 0,011857 0,045230 0,182405RAZEM 0,096515 0,382207 1,571402 7,193269

Tabela 13: Czas działania dla dekompresji obrazów CUDA w sekundach

57

Page 61: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

256x128 512x256 640x360OpenCV open 0,193679 1,270311 1,479300Transformata kolorów 0,074103 0,293666 0,516504Transformata falkowa 7,813984 31,581902 36,333046Linearyzacja 0,055390 0,186920 0,327388Optymalizacja RD 9,268871 34,757854 60,533020Kwantyzacja i kodowanie arytm. 0,845549 3,356462 5,920140RAZEM 18,251576 71,447115 105,109398

Tabela 14: Czas działania dla kompresji wideo CPU w sekundach

256x128 512x256 640x360OpenCV open 0,192346 1,283418 1,483076CUDA malloc 0,000080 0,001169 0,000623CUDA host → device 0,034953 0,148364 0,290110CUDA transformata kolorów 0,004485 0,017685 0,036854CUDA transformata falkowa 2,651940 10,222892 14,795855CUDA device → host 0,046034 0,176791 0,296816Linearyzacja 0,056424 0,186734 0,326103Optymalizacja RD 9,320011 34,808395 60,633026Kwantyzacja i kodowanie arytm. 0,827814 3,323836 5,872478RAZEM 13,134087 50,169284 83,734941

Tabela 15: Czas działania dla kompresji wideo CUDA w sekundach

256x128 512x256 640x360OpenCV save 0,392186 1,781573 2,693752Transformata kolorów 0,059673 0,236618 0,413091Transformata falkowa 10,922973 44,181793 55,494530Delinearyzacja 0,052526 0,187883 0,337915Dekodowanie i dekwantyzacja 1,205501 4,757320 8,300419RAZEM 12,632859 51,145187 67,239707

Tabela 16: Czas działania dla dekompresji wideo CPU w sekundach

256x128 512x256 640x360OpenCV save 0,492696 2,184490 3,434199Delinearyzacja 0,052753 0,188992 0,334865Dekodowanie i dekwantyzacja 1,221008 4,733652 8,288025CUDA malloc 0,000552 0,000738 0,000509CUDA host → device 0,032174 0,164386 0,215942CUDA transformata kolorów 0,004426 0,017633 0,036558CUDA transformata falkowa 1,606770 6,311075 8,970387CUDA device → host 0,035390 0,143260 0,248643RAZEM 3,445769 13,744226 21,529128

Tabela 17: Czas działania dla dekompresji wideo CUDA w sekundach

58

Page 62: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

9 Podsumowanie

W niniejszej pracy zaprezentowane zostały poszczególne kroki wykonywane przez

stratny kompresor falkowy. Opis poszczególnych algorytmów uzupełniony jest o przykłady

dla łatwiejszego zrozumienia ich działania. Przedstawiłem również krótki opis technolo-

gii NVIDIA CUDA skupiając się na elementach wykorzystanych przy implementacji. W

ramach pracy wykonany został stratny koder falkowy umożliwiający wykonywanie części

obliczeń na procesorze GPU. Aplikację zweryfikowałem pod kątem efektywności kompresji

oraz szybkości działania.

W pracy składającej się z dziewięciu rozdziałów przedstawiłem najpierw teoretyczne

podstawy dotyczące transformaty falkowej. Schemat obliczania współczynników falkowych

przedstawiony jest na prostym przykładzie dla lepszego zrozumienia charakteru transfor-

maty falkowej. Opisane są kwestie związane z transformatą sygnałów wielowymiarowych

i zachowaniem na granicach. W kolejnym rozdziale zaprezentowałem klasyczny schemat

kwantyzacji skalarnej z dwoma wariantami (kwantyzacja równomierna i kwantyzacja rów-

nomierna z rozszerzonym przedziałem zerowym). Bezstratny krok kompresji realizowany

przez koder arytmetyczny opisany jest w rozdziale czwartym. Wszystkie przedstawione

algorytmy opisane są w kontekście ich wykorzystania przy kompresji. Dzięki temu oraz

dzięki licznym przykładom, praca może stanowić materiał dydaktyczny dla osób chcących

zapoznać się z falkową kompresją stratną.

Opis proponowanego rozwiązania i jego implementacji skupia się na implementacji

GPU. Na procesorze graficznym udało się zrealizować kroki związane z transformatą ko-

lorów i transformatą falkową. Kodowanie arytmetyczne ze względu na swój sekwencyj-

ny charakter nie nadaje się do zrównoleglenia. Naturalnym kandydatem do wykonania

na GPU wydaje się krok kwantyzacji. Wykorzystany przeze mnie algorytm optymaliza-

cji RD, w którym koszt bitowy jest precyzyjne obliczany przez zakodowanie każdego z

współczynników, sprawia, że kwantyzacja na GPU zwiększa czas działania. Dzięki wyko-

rzystaniu technologii NVIDIA CUDA udało mi się uzyskać kilkukrotne szybsze wykonanie

kroku obliczania transformaty falkowej (blisko dziesięciokrotne dla transformaty dwuwy-

miarowej i 3-4 krotne dla transformaty trójwymiarowej). Wąskim gardłem przy kompresji

wykorzystującej GPU jest optymalizacja RD i zajmuje ona do 85 procent czasu wykona-

nia.

Uzyskane wyniki stopnia kompresji świadczą o umiarkowanej efektywności wykonane-

go rozwiązania. Wynika to przede wszystkim z dość trywialnego kodera arytmetycznego.

Standard JPEG2000 wykorzystuje binarny koder arytmetyczny z modelowaniem staty-

stycznym wysokiego rzędu (MQ-Coder) [8]. Bardzo skutecznym rozwiązaniem jest również

połączenie transformaty falkowej z wykorzystaniem zero-drzew [18]. Wariacja tej meto-

dy wykorzystywana jest przez jeden najskuteczniejszych obecnie kompresorów stratnych

59

Page 63: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

SPIHT [17]. Zastosowanie jednej z tych metod umożliwiłoby uzyskanie wyższej efektyw-

ności kompresji.

Podsumowując w ramach pracy przedstawiłem algorytmy niezbędne do zrealizowania

kompresji stratnej przy użyciu metod falkowych. Zaprojektowałem i zaimplementowa-

łem kompletny kompresor falkowy umożliwiający kompresję obrazów i sekwencji wideo w

oparciu o wybrane algorytmy. Zrealizowana przeze mnie aplikacja wykorzystuje technolo-

gię NVIDIA CUDA w celu przyśpieszenia czasu wykonania. Dzięki modularnej budowie

można łatwo rozszerzyć istniejący kompresor o inne rodzaje kwantyzatorów, koderów aryt-

metycznych czy filtrów falkowych. Aplikacja może być z powodzeniem wykorzystywana w

celach dydaktycznych.

60

Page 64: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

Bibliografia

[1] Jan T. Białasiewicz. Falki i aproksymacje. Wydawinctwo Naukowo-Techniczne, War-

szawa, 2000.

[2] Chorng-Yann Su Bing-Fei Wu. A fast convolution algorithm for biorthogonal wavelet

image compression. 1999.

[3] Chris Brislawn. Classification of nonexpansive symmetric extension transforms for

multirate filter banks. Los Alamos Tech Report LA-UR-94-1747, 1994.

[4] Ingrid Daubechies. Ten Lectures on Wavelets. SIAM: Society for Industrial and

Applied Mathematics, 1992.

[5] Wen-mei W. Hwu David B. Kirk. Programming Massively Parallel Processors: A

Hands-on Approach. Morgan Kaufman, Burlington, 2010.

[6] Joachim Kneis Eric Bodden, Malte Clasen. Arithmetic coding revealed - a guided

tour from theory to praxis. 2007.

[7] David H. Salesin Eric J Stollnitz, Tony D. DeRose. Wavelets for computer graphics:

A primer, part 1. IEEE Computer Graphics and Applications, 15(3), 1995.

[8] JPEG. ”JPEG 2000 Core coding system (Part 1)”, 2000.

[9] Stephane Mallat. A Wavelet Tour of Signal Processing. Academic Press, 1998.

[10] Pierre Mathieu Ingrid Daubechies Marc Antonini, Michel Barlaud. Image coding

using wavelet transform. 1992.

[11] Jean-loup Gailly Mark Nelson. The Data Compression Book. M&T Books, New

York, 1995.

[12] Margaret A. Lepleyb Michael W. Marcellina. An overview of quantization in jpeg

2000. Signal Processing: Image Communication 17, 2002.

[13] NVIDIA. ”NVIDIA CUDA C Programming Best Practices Guide”, 2010.

[14] NVIDIA. ”NVIDIA CUDA Programming Guide”, 2010.

61

Page 65: Praca dyplomowa inżynierska Stanisław Ogórkis - ogorkis.netogorkis.net/resources/praca_inz_Stanislaw_Ogorkis.pdf · Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych

[15] Artur Przelaskowski. Falkowe metody kompresji danych obrazowych. 2002.

[16] Artur Przelaskowski. Kompresja danych: podstawy, metody bezstratne, kodery obra-

zów. Wydawnictwo BTC, Warszawa, 2005.

[17] Pearlman William A. Said, Amir. A new fast and efficient image codec based on set

partitioning in hierarchical trees. 1996.

[18] Jerome M. Shapiro. Embedded image coding using zerotrees of wavelet coefficients.

1993.

[19] W. Skarbek. Multimedia. Algorytmy i standardy kompresji. Akademicka Oficyna

Wydawnicza PLJ, Warszawa, 1998.

[20] A. Gersho Y. Shoham. Efficient bit allocation for an arbitrary set of quantizers.

IEEE Transactions on Acoustics, Speech, and Signal Processing, Vol. 36, 1988.

62