• Nie Znaleziono Wyników

Przyczyny niepełnej zgodności wyników przewidywań i doświadczeń

6. Automatyczna analiza grafu

6.10. Przyczyny niepełnej zgodności wyników przewidywań i doświadczeń

Przyczyny rozbieżności pomiędzy wynikami uzyskanymi w drodze analizy grafu oraz doświadczeń mogą mieć źródło zarówno w niedokładnościach pomiarów, jak i ograniczeniach programu analizującego. Najbardziej prawdopodobnymi przyczynami niezgodności wyników są:

• zbyt mała liczba przeprowadzonych doświadczeń,

• generowanie przerwań zakłócających pomiar czasu następnego bloku, • opóźnienia wprowadzane przez protokół sieciowy,

• wpływ pamięci podręcznej na szybkość realizacji kodu, • ładowanie kodu programu w trakcie jego wykonywania, • usypianie i budzenie procesów oczekujących na komunikację, • niedokładna metoda pomiaru czasu przesyłania danych przez sieć, • niejawna konkurencja o dostęp do sieci,

• założenie normalnego kształtu rozkładu czasu realizacji programu. • założenie braku korelacji czasu wykonywania kolejnych bloków

Za mała próbka

Otrzymane wyniki wskazują, że liczba doświadczeń w niektórych przypadkach była zbyt mała. Często jednak zwiększenie liczby doświadczeń nie było możliwe ze względów czasowo-organizacyjnych. Dla niezależnych pomiarów szybkości wykonywania poszczególnych fragmentów kodu widoczne są znaczne różnice czasu dla obu (identycznych) maszyn, co teoretycznie nie powinno mieć miejsca. Spowodowane są one przerwaniami systemu operacyjnego wprowadzającymi duże opóźnienia, aczkolwiek z występującymi z małym prawdopodobieństwem. Aby uzyskać pełniejszy obraz rozkładu losowego należałoby przeprowadzić

zdecydowanie więcej doświadczeń (które trwałyby tygodniami) lub określić zdarzenia mało prawdopodobne na drodze teoretycznej.

Przerwania zakłócające pomiar czasu kolejnych bloków

Instrukcje asynchronicznej komunikacji składają się z części jawnej – wykonywanej jako funkcja programu użytkownika, oraz niejawnej inicjowanej przez przerwanie sprzętowe. Przerwanie i związany z nim narzut czasowy może wystąpić w momencie wykonywania innego fragmentu programu niż ten, który go wywołał. Powoduje to przekłamania w pomiarze czasu wykonywania fragmentów programu. Częściowym rozwiązaniem jest pomiar szybkiego, n-krotnego wykonania tego samego fragmentu. Przerwania generowane przez ten fragment zostaną wtedy zaliczone w poczet czasu wykonania tego samego fragmentu w którymś z kolejnych kroków pomiarowych. Problem w takim przypadku może stanowić przeciążenie interfejsu sieciowego żądaniami nadchodzącymi znacznie szybciej niż w normalnym programie.

Protokół sieciowy

Zaawansowany protokół sieciowy wymaga dokonania wielu czynności wstępnych umożliwiających uruchomienie interfejsu i przesłanie pakietu. Część z nich jest dokonywana w momencie inicjowania komunikacji, część przed wysłaniem pakietu. W szczególności system musi sprawdzić i ew. uzupełnić informację dotyczącą routingu i ARP. W związku z tym wysłanie pierwszego pakietu obarczone jest dodatkowym narzutem czasowym. Przy wysyłaniu dalszych system korzysta z kopii podręcznych. Obserwując wyniki pomiarów można stwierdzić, że pierwsza instrukcja send() wykonuje się o 30-50% dłużej niż kolejne.

Pamięć podręczna

Ze względy na ograniczoną pojemność pamięci podręcznej obserwowany jest efekt szybszego wykonywania fragmentu kodu, kiedy jest on n-krotnie wykonywany w procedurze pomiarowej, niż później we właściwym programie. Rozbieżności spowodowane tym zjawiskiem można zniwelować umieszczając w procedurze pomiaru szybkości fragmentu dodatkowy kod mający za zadanie wypełnienie pamięci podręcznej w stopniu zbliżonym do właściwego programu. Trudność może nastręczać oszacowanie stopnia użycia pamięci podręcznej przez właściwy program.

Ładowanie na żądanie

Większość systemów operacyjnych umożliwia szybki start programu i oszczędność pamięci dzięki mechanizmowi ładowania na żądanie. Do pamięci ładowane są tylko te strony kodu programu, które są rzeczywiście potrzebne. Innymi słowy wystąpienie błędu strony powoduje jej załadowanie z pliku zawierającego treści programu. Operacja ładowania brakującego kodu wymaga czasu, zatem pierwsze wykonanie danego fragmentu będzie trwało dłużej niż następne iteracje.

Powolne „budzenie” procesu

Jeżeli dane odbierane przez recv() nie dotarły jeszcze do komputera, proces odbierający jest wprowadzany w stan uśpienia, a procesor przystępuje do wykonywania innych zadań. Po nadejściu żądanej informacji proces oczekujący jest ponownie przywracany do normalnego stanu i kontynuowany. Operacja usypiania i budzenia

pakietu może wywołać dużą różnicę czasu wykonania instrukcji odbioru. Zaprzecza to częściowo tezie, że synchronizacja pozytywna prowadzi zawsze do wyrównania szybkości poszczególnych procesów. Dla zagadnienia o rozmiarze 4x4 wyraźnie zaobserwowano kolejne wysuwanie się na prowadzenie raz jednego, raz drugiego procesu. Czas wykonania instrukcji odbioru oscylował pomiędzy wartością 450 µsec a 18 µsec.

Niedokładny pomiar czasu przesyłania komunikatu przez sieć

Ze względu na trudności pomiaru opóźnienia przesyłania danych przez sieć dokonano pomiaru szybkości procedury symulującej komendę ping a następnie „odjęto” czas wykonania instrukcji send() i recv(). Przyjęta metoda nie zapewnia dużej dokładności, zwłaszcza w odniesieniu do wcześniej poruszanych problemów związanych z pomiarem szybkości komend send() i recv(). Jej zaletą jest jednak uniwersalność, dostępność i brak ingerencji w system operacyjny. Dodatkowo komenda ping nie powoduje konkurowania systemów o dostęp do kanału, natomiast w rzeczywistym programie ze względu na symetrię komunikacji sytuacja taka będzie występować stosunkowo często.

Niejawna konkurencja o dostęp do sieci

W programie „life” przyjęte jest założenie, że oba procesy mogą jednocześnie wysłać komunikat. Gdy komputery połączone są pojedynczym segmentem sieci ethernet następuje niejawna konkurencja o dostęp do niepodzielnego kanału. Powoduje ona dodatkowe czasy oczekiwania na zwolnienie kanału, kolizje pakietów, generację nadprogramowych przerwań.

Założenie normalności rozkładu dla dużych wariancji

Rozkład losowy czasu wykonania fragmentu programu swoim kształtem znacznie odbiega od rozkładu normalnego. W rzeczywistym rozkładzie maksimum gęstości jest położone w obszarze liczb wyraźnie mniejszych od wartości średniej. Przyjęcie do obliczeń rozkładów normalnych równoważnych, co do wartości średniej i odchylenia powoduje duży błąd obliczeń. Jest on szczególnie istotny przy liczeniu rozkładu maksimum z dwóch liczb losowych. Przy liczeniu pochodnej iloczynu dystrybuant ważniejsze jest maksimum gęstości rozkładu niż jego wartość średnia. W wyniku pomiarów otrzymano rozkłady, dla których odchylenie standar-dowe znacznie przekracza wartość oczekiwaną, co kłóci się z założeniem o nieujemnym czasie wykonywania dowolnej czynności. Stosowanie rozkładu normalnego o takich parametrach prowadzi do poważnych błędów w obliczeniach. W związku z tym przy analizie rozkładów losowych o dużych wariancjach powinny one być przybliżane raczej rozkładem wykładniczym (przesuniętym) niż normalnym.

Założenie braku korelacji czasu wykonywania kolejnych bloków

W przyjętej metodzie założono, że czasy realizacji poszczególnych bloków są od siebie niezależne. W rzeczywistym systemie, istnieje duże prawdopodobieństwo zmniejszenia szybkości procesora podczas wykonywania kilku kolejnych bloków. Zdarzenie zewnętrzne lub wywołane działalnością systemu operacyjnego może obciążać procesor przez dłuższy czas, jak również spowodować wypełnienie pamięci podręcznych inną zawartością, co spowoduje wydłużenie czasu wykonywania kilku kolejnych bloków.