Subsections

7 Wyniki testów

1 Wstęp

W ramach pracy magisterskiej przeprowadzone zostały testy badające wydajność podsystemu komunikacyjnego SockZCCL. Do testów użyto aplikacji korzystających z ZCCL, opisanych w rozdziale 6. Jako punkt odniesienia dla wyników SockZCCL przyjęto wyniki analogicznych aplikacji, używających bezpośrednio biblioteki gniazd. Aplikacje te są pokrótce opisane w p. 7.4.

Przeprowadzono 4 testy.

W teście 1 zbadano szybkość przesyłania komunikatów na kanale Message.

W teście 2 porównano działanie aplikacji w trybie jądra i w trybie użytkownika.

Celem testu 3 było zmierzenie czasu odpowiedzi przy przesyłaniu komunikatów poprzez kanał Message.

W teście 4 zmierzono przepustowość ZCCL przy pracy w modelu żądanie-odpowiedź, w którym żądanie wysyłane jest kanałem Message, a odpowiedź przychodzi kanałem Post.

2 Środowisko testowe

1 Sprzęt

Testy przeprowadzono z użyciem dwóch komputerów:

Testy przeprowadzono w sieci lokalnej typu 10 Mbit Ethernet, komputery były połączone poprzez koncentrator.

2 Oprogramowanie

Oba komputery działały pod kontrolą systemu operacyjnego Linux. Do testów użyto jądra w wersji 2.4.2-2 dostarczanego z dystrybucją RedHat 7.1 oraz jego zmodyfikowanej wersji 2.4.2-2sockwrap.

Jądro 2.4.2-2sockwrap różni się od jądra 2.4.2-2 tylko eksportowaniem symboli niezbędnych do załadowania modułu zawierającego wersję ZCCL pracującą w trybie jądra.

3 Program testujący

Wszystkie aplikacje testowe umieszczono w jednym pliku wykonywalnym (programie lub module jądra).

Przy pracy w trybie użytkownika wybór testowanej aplikacji był dokonywany na podstawie argumentów wywołania programu testującego.

Aplikacje testowe pracujące w trybie jądra zrealizowano w postaci modułu do jądra Linuksa. Uruchamianie aplikacji odbywało się poprzez dokonanie zapisu do odpowiedniego pliku w systemie plików proc.

3 Sposób pomiaru

Mierzono całkowity czas wykonania testu, od rozpoczęcia do zakończenia.

Mierzenie czasu odbywało się w samej aplikacji testowej, więc czas załadowania programu testującego nie jest uwzględniony w wynikach.

Czas był mierzony dla 5 przebiegów testu, ostateczny wynik był średnią arytmetyczną z tych 5 przebiegów.

Na czas testów wyłączono wszystkie aplikacje i programy usługowe (demony) mogące wpłynąć na wyniki testu, takie jak serwer poczty, czy demon crond.


4 Aplikacje testowe dla gniazd

Na potrzeby przeprowadzenia testów porównawczych stworzono aplikacje analogiczne do aplikacji przygotowanych dla ZCCL, ale używające do przesyłania danych bezpośrednio biblioteki gniazd.

1 Aplikacja 1way-gniazda

Aplikacja ta realizuje podobne zadanie co aplikacja 1way.

Wysyłaniem i odbieraniem danych zajmuje się jeden wątek. Po stronie klienta wątek ten w pętli wysyła kolejne komunikaty, a po stronie serwera w pętli odbiera komunikaty.

Każdy komunikat składa się z nagłówka zawierającego długość komunikatu i treści komunikatu. Dodanie nagłówka przed właściwymi danymi pozwala symulować sposób przesyłania komunikatów przez bibliotekę ZCCL, która musi obsługiwać komunikaty zmiennej długości.

2 Aplikacja pingpong-gniazda

Aplikacja ta realizuje podobny model komunikacji co aplikacja pingpong.

Używany jest jeden wątek, który w pętli na przemian odbiera komunikat i wysyła odpowiedź.

Ta aplikacja posiada dwie wersje: jedna wysyła przed komunikatem nagłówek zawierający rozmiar komunikatu, a druga wysyła samą treść komunikatu (który jest stałego, znanego z góry rozmiaru).

3 Aplikacja post-gniazda

Aplikacja ta jest uproszczoną wersją aplikacji post. Różni się przede wszystkim użyciem tylko jednego połączenia TCP, które służy do przesyłania żądań i odpowiedzi.

Aplikacja posiada jeden wątek, który w pętli odbiera żądanie i od razu wysyła odpowiedź. Żądanie jest przesyłane jako komunikat o długości 4 bajtów, zaś odpowiedź to komunikat o rozmiarze określonym w parametrach testu.

5 Test 1

1 Cel testu

Celem tego testu jest zbadanie szybkości przesyłania komunikatów kanałem Message i określenie narzutu wprowadzanego przez ZCCL.

2 Opis testu

Do przeprowadzenia testu dla ZCCL użyto aplikacji 1way. Przesyłano 50000 komunikatów o rozmiarach od 4 do 1024 bajtów.

Jako punkt odniesienia przyjęto szybkość przesyłania komunikatów przez aplikację 1way-gniazda.

Klient działał na komputerze A, a serwer na komputerze B -- oba w trybie użytkownika.

3 Wyniki

Wyniki przedstawiono jako liczbę komunikatów przesłanych na sekundę dla każdego rozmiaru komunikatu (por. tabela 7.1).

Stosunek jest obliczony jako:

(wartość zmierzona dla ZCCL/wartość dla gniazd)*100%

Wyniki każdego wykonania są średnią arytmetyczną z 5 przebiegów testu.


Tabela 7.1: Wyniki testu 1
Rozmiar komunikatu 4 8 16 32 64 128 256 512 1024
Gniazda (kom./s) 37448 35893 32238 31392 16648 8581 4358 2196 1102
ZCCL (kom./s) 9467 9434 9158 8921 8068 6939 4356 2194 1102
Stosunek(%) 25,29 26,29 25,52 28,42 48,47 80,87 99,96 99,91 100


Na rysunku 7.1 znajduje się wykres przedstawiający zależność liczby przesłanych komunikatów od rozmiaru komunikatu, dla ZCCL i gniazd. Skala na osi Y jest logarytmiczna.



Rysunek 7.1: Wyniki testu 1
\resizebox*{1\textwidth}{!}{\includegraphics{rysunki//wykres-1way-1.eps}}



4 Wnioski

Dla małych komunikatów narzut wprowadzany przez ZCCL jest wyjątkowo duży. Malejąca wraz ze wzrostem komunikatu rozbieżność pomiędzy gniazdami a ZCCL wskazuje, że jest to narzut związany z wysłaniem jednego komunikatu, a nie z samą transmisją danych.

Powodem dużego kosztu wysłania komunikatu jest wysyłanie komunikatów z osobnego wątku. Wymaga to przełączenia kontekstu do wątku wysyłającego, co w przypadku ciężkich wątków realizowanych przez bibliotekę pthreads oznacza konieczność przejścia do trybu jądra i przeszeregowania procesów.

6 Test 2

1 Cel testu

Celem testu jest porównanie szybkości transmisji w trybie jądra i trybie użytkownika.

2 Opis testu

Do przeprowadzenia testu dla ZCCL użyto aplikacji 1way. Przesyłano 100000 komunikatów o rozmiarze 32 bajtów.

Jako punkt odniesienia przyjęto szybkość przesyłania komunikatów przez aplikację 1way-gniazda.

Każdy test przeprowadzono w czterech konfiguracjach:

  1. Zarówno po stronie klienta, jak i po stronie serwera aplikacja działa w trybie użytkownika. Ta konfiguracja jest oznaczana dalej jako UU.
  2. Aplikacja po stronie klienta działa w trybie jądra, po stronie serwera w trybie użytkownika. Ta konfiguracja jest oznaczana dalej jako KU.
  3. Aplikacja po stronie klienta działa w trybie użytkownika, po stronie serwera w trybie jądra. Ta konfiguracja jest oznaczana dalej jako UK.
  4. Zarówno po stronie klienta, jak i po stronie serwera aplikacja działa w trybie jądra. Ta konfiguracja jest oznaczana dalej jako KK.
Klient działał na komputerze A, a serwer na komputerze B.

3 Wyniki

Wyniki są przedstawione jako przepustowość mierzona jako liczba kilobajtów (tysięcy bajtów) na sekundę. Każdy wynik jest średnią arytmetyczną z 5 przebiegów testu.

Wyniki testu zawiera tabela 7.2.


Tabela 7.2: Wyniki testu 2
Konfiguracja UU KU UK KK
Gniazda (kB/s) 780,2 779,6 1005,8 1006,2
ZCCL(kB/s) 267,0 263,6 598,0 626,5


Tabela 7.3 przedstawia przyrost przepustowości określony jako stosunek uzyskanej przepustowości (wyrażony w procentach) względem konfiguracji UU, czyli obu aplikacji działających w trybie użytkownika.


Tabela 7.3: Przyrost przepustowości w teście 2
Konfiguracja UU KU UK KK
Gniazda (%) 100 99,93 128,92 128,97
ZCCL(%) 100 98,73 223,98 234,65


Rysunek 7.2 ilustruje przepustowość uzyskaną w każdej konfiguracji dla ZCCL i gniazd.

Rysunek 7.2: Wyniki testu 2
\resizebox*{0.8\columnwidth}{!}{\includegraphics{rysunki//wykres-1way-2.eps}}

4 Wnioski

Użycie aplikacji działającej w trybie jądra po stronie serwera, działającego na maszynie wolniejszej, powoduje widoczną poprawę przepustowości. Wynika z tego, że duży wpływ na wydajność ma czas przejścia do trybu jądra. Na słabszym procesorze czas ten w znaczący sposób wpływa na szybkość z jaką aplikacja jest w stanie odbierać dane. Poprawa przepustowości dla ZCCL jest dużo większa niż dla gniazd i wynika z częstszego przechodzenia do trybu jądra. Na przykład ZCCL (a w zasadzie SockZCCL) przed wysłaniem danych wywołuje funkcję poll() w celu sprawdzenia, czy należy przerwać komunikację.

Praca w trybie jądra po stronie klienta nie ma znaczącego wpływu na szybkość działania, ponieważ czynnikiem ograniczającym przepustowość jest szybkość pracy serwera na słabszej maszynie.

Zaskakujący jest spadek przepustowości w konfiguracji z klientem działającym w trybie jądra i serwerem działającym w trybie użytkownika. Spadek ten wynosi 0,07% dla gniazd i 1,27% dla ZCCL. Kiedy serwer działa w trybie jądra, odnotowywany jest, zgodnie z oczekiwaniami, wzrost wydajności, mimo że stosunkowo niewielki. Sugeruje to, że ten spadek wydajności jest spowodowany niekorzystnym zachowaniem stosu TCP/IP w tym akurat przypadku. Zbyt szybkie dostarczanie danych do wysłania do stosu TCP/IP może spowodować konieczność wstrzymywania działania w oczekiwaniu na wolne miejsce u odbiorcy, co wiąże się z uśpieniem wątku. Gdy dane są dostarczane wolniej, odbiorca może zdążyć z ich odbieraniem i w związku z tym wątek wysyłający dane może rzadziej zasypiać. Dzięki temu efektywna szybkość przesyłania danych może być wyższa.

7 Test 3

1 Cel testu

Celem tego testu jest zmierzenie czasu odpowiedzi (przesłania komunikatu do serwera i z powrotem) przy przesyłaniu komunikatów.

2 Opis testu

Do przeprowadzenia testu dla ZCCL użyto aplikacji pingpong. Przesyłano 5000 komunikatów o rozmiarach od 4 do 1024 bajtów.

Jako punkt odniesienia przyjęto szybkość przesyłania komunikatów przez aplikację 1way-pingpong, przy czym komunikaty wysyłane przez tę aplikację nie zawierały nagłówka z rozmiarem komunikatu. Powód takiego działania jest opisany w punkcie 7.7.5.

Klient działał na komputerze A, a serwer na komputerze B. Zarówno klient, jak i serwer działały w trybie użytkownika.

3 Wyniki

Wyniki przedstawiono jako czas odpowiedzi (RTT -- ang. round trip time) wyrażony w mikrosekundach (por. tabela 7.4).

Czas odpowiedzi obliczono przez podzielenie 1000000 przez średnią liczbę komunikatów przesłanych w ciągu sekundy.

Stosunek wskazuje spowolnienie ZCCL w stosunku do gniazd i jest obliczony ze wzoru:

((czas dla ZCCL-czas dla gniazd)/czas dla gniazd) -1)* 100%

Wyniki każdego wykonania są średnią arytmetyczną z 5 przebiegów testu.

Należy pamiętać o tym, że aplikacja pingpong-gniazda nie przesyła nagłówka zawierającego rozmiar komunikatu, co dla mniejszych rozmiarów komunikatów stanowi znaczącą część komunikatu.


Tabela 7.4: Wyniki testu 3
Rozmiar komunikatu 4 8 16 32 64 128 256 512 1024
Gniazda ($ \mu$s) 508 516 531 564 627 753 1007 1528 2566
ZCCL ($ \mu$s) 843 862 862 893 966 1091 1354 1878 2921
Stosunek(%) 65,95 67,06 62,34 58,34 54,07 44,89 34,46 22,91 13,84
Różnica ($ \mu$s) 335 346 331 329 339 338 347 350 355


Na rysunku 7.3 znajduje się wykres przedstawiający czas odpowiedzi dla gniazd i ZCCL.

Rysunek 7.3: Wyniki testu 3
\includegraphics[]{..//src//tests//pingpong-3//wykres1.eps}

4 Wnioski

Czas odpowiedzi dla ZCCL jest dłuższy ze względu na konieczność przełączenia kontekstu między wątkiem aplikacji a wątkiem wysyłającym. Wskazuje na to niezależna od rozmiaru komunikatu różnica między czasem odpowiedzi dla ZCCL i gniazd, wynosząca około 340 mikrosekund.


5 Problemy napotkane w czasie testu

Początkowo w tym teście jako punkt odniesienia miała być wykorzystana aplikacja pingpong-gniazda, w której przed przesłaniem właściwego komunikatu przesyłano nagłówek zawierający rozmiar komunikatu. Jednak czas odpowiedzi uzyskany dla tej aplikacji był niewytłumaczalnie długi, około stukrotnie większy od czasu zmierzonego dla ZCCL.

Test powtórzono wiele razy w różnych konfiguracjach, zawsze z tym samym skutkiem. Użycie różnych funkcji do transmisji danych (np. sendmsg() zamiast send()) nie ma wpływu na występowanie tego efektu.

Taka anomalia występowała niezależnie od tego, czy klient i serwer komunikowały się przez sieć, czy działały na jednej maszynie.

Na rysunku 7.4 przedstawiono wyniki testu przeprowadzonego na jednej maszynie (maszyna A).

Rysunek 7.4: Czas odpowiedzi dla aplikacji pingpong-gniazda przesyłającej komunikaty z nagłówkami
\includegraphics[]{..//src//tests//pingpong-4//wykres1.eps}

Przesyłano 100 komunikatów.

Niezależnie od rozmiaru komunikatu test wykonywał się w około 7,95 sekundy, co odpowiada przesyłaniu około 12.56 komunikatu na sekundę, czyli czasowi odpowiedzi rzędu 79500 mikrosekund.

Uruchomienie aplikacji pod nadzorem programu śledzącego odwołania do funkcji systemowych wykazuje, że opóźnienie występuje w momencie odbierania treści komunikatu i wysyłania nagłówka komunikatu. W obu przypadkach czas spędzony w wywołaniu funkcji systemowej sięga prawie 0.04 sekundy (sic!). Ślad wykonania tej aplikacji umieszczono w dodatku A.

Wytłumaczenie takiej anomalii jest trudne. Najbardziej prawdopodobnym wyjaśnieniem jest niekorzystne zachowanie stosu TCP/IP przy takim przeplocie wykonywania operacji transmisji danych. W takim wypadku rozwiązaniem mogłoby być ustawienie stosu TCP w trybie przesyłania danych bez oczekiwania na dodatkowe dane (ang. no-delay) lub użycie podobnej w działaniu opcji TCP_CORK.

8 Test 4

1 Cel testu

Celem tego testu jest zbadanie szybkości przesyłania danych w modelu przesyłania danych typu żądanie-odpowiedź, gdzie żądanie jest krótkim komunikatem, natomiast odpowiedź składa się z dużej ilości danych.

2 Opis testu

Do przeprowadzenia testu dla ZCCL użyto aplikacji post. Przesyłano 1000 transmisji o rozmiarach od 1024 do 65536 bajtów.

Jako punkt odniesienia przyjęto szybkość przesyłania danych przez aplikację post-gniazda.

Klient działał na komputerze A, a serwer na komputerze B. Oba działały w trybie użytkownika.

3 Wyniki

Wyniki przedstawiono jako przepustowość wyrażoną w kilobajtach (tysiącach bajtów) na sekundę (por. tabela 7.5).

Stosunek jest obliczony jako:

(wartość zmierzona dla ZCCL/wartość dla gniazd)*100%

Wyniki każdego wykonania są średnią arytmetyczną z 5 przebiegów testu.


Tabela 7.5: Wyniki testu 4
Rozmiar komunikatu 1024 2048 4096 8192 16384 32768 65536
Gniazda(kB/s) 664,82 807,68 965,52 1028,87 1078,18 1110,7 1121,35
ZCCL (kB/s) 402,08 636,98 817,34 949,83 1035,00 1082,77 1107,62
Stosunek(%) 60,48 78,87 84,66 92,32 96,00 97,49 98,78


Na rysunku 7.5 znajduje się wykres przedstawiający zależność przepustowości od rozmiaru komunikatu dla ZCCL i gniazd.



Rysunek 7.5: Wyniki testu 4
\includegraphics[]{..//src//tests//pingpong-3//wykres1.eps}



4 Wnioski

Słaba przepustowość ZCCL dla mniejszych rozmiarów komunikatów wynika z dużego kosztu wysłania komunikatu z żądaniem, które wymaga przełączenia kontekstu z wątku aplikacji na wątek wysyłający, oraz z podobnego kosztu związanego z wysłaniem odpowiedzi. Odebranie komunikatu następuje w wątku odbiorczym kanału Message, więc w celu wysłania danych poprzez kanał Post musi nastąpić przełączenie na wątek wysyłający kanału Post. Aplikacja post-gniazda w jednym wątku w sekwencyjny sposób odbiera żądania i wysyła odpowiedzi, więc może uzyskać maksymalną przepustowość.

Wraz ze wzrostem rozmiaru komunikatu maleje liczba koniecznych przełączeń kontekstu i przepustowość ZCCL osiąga wartość zbliżoną do przepustowości gniazd.

9 Podsumowanie testów

Podsystem komunikacyjny SockZCCL nie został zaprojektowany z myślą o wydajności i widać to wyraźnie w wynikach przeprowadzonych testów. Należy jednak pamiętać, że jest to podsystem używany przede wszystkim do testowania koncepcji ZCCL i przy jego projektowaniu brano pod uwagę głównie łatwość implementacji.

Najważniejszym wnioskiem z przeprowadzonych testów jest to, że największy wpływ na wydajność ma konieczność przełączenia kontekstu przy wysyłaniu, spowodowana realizacją wysyłania tylko w obrębie wątku wysyłającego. Wpływ tego widać we wszystkich testach. Wada ta dotyczy zarówno kanału Message, jak i kanału Post. Ilustracją tego zjawiska jest rysunek 7.6.

Rysunek 7.6: Koszt przełączenia kontekstu przy wysyłaniu danych
\includegraphics[]{..//src//tests//pingpong-3//wykres1.eps}

Rozwiązaniem problemu powinna być taka realizacja operacji wysyłania, by transmisja danych, w miarę możliwości, została przeprowadzona od razu, w kontekście wątku aplikacji. Dopiero możliwość zablokowania wątku przy wysyłaniu powinna powodować przekazanie żądania wysłania do wątku wysyłającego do późniejszego przesłania.

Pocieszający jest fakt, że w zakładanym zastosowaniu ZCCL, czyli transmisji dużych ilości danych w modelu żądanie-odpowiedź, wydajność ZCCL jest zbliżona do wydajności gniazd. Dla 8-kilobajtowych, i większych, bloków danych przepustowość jest na poziomie 1 megabajta na sekundę, co nie odbiega wiele od przepustowości gniazd i powinno wystarczyć do efektywnego przesyłania danych plików.

Krzysztof Lichota 2002-06-24