Przykładowa implementacja estymatora może używać wykładniczej ważonej średniej ruchomej (jak w RED). Niech $s$ będzie wielkością ostatnio wysłanego pakietu w bajtach, $b$ pasmem przydzielonym klasie w ramach współdzielenia łącza, a $t$ czasem pomiędzy końcem wysyłania ostatniego pakietu a poprzedzającego go. Idealny czas pomiędzy końcami wysłania tych pakietów oznaczmy jako: $$f(s,b) = s/b$$ a różnice między czasem idealnym a rzeczywistym jako $$\mathit{diff} = t - f(a,b)$$ Można zauważyć, że klasa przekracza swój udział jeśli $\mathit{diff} < 0$. Zmiany tej różnicy można więc śledzić by wykrywać, kiedy klasa jest nad limitem. Zatem ze wzoru na średnią ruchomą mamy: $$avg \leftarrow (1-w)avg + w \cdot \mathit{diff} $$ Optymalizację co do parametrów można przeprowadzić taką samą jak dla RED, tzn. tak, by między innymi waga $w$ była ujemną potęgą dwójki, co pozwala uproscić mnożenie do przesunięcia. Waga ta jest parametrem estymatora i mówi, że po wysłaniu $\frac{1}{ln(1-w)}$ pakietów, $avg$ przemieści się o $64\%$ odległości między poprzednią wartością $\mathit{diff}$ a nową. Biorąc pod uwagę przydział danej klasy, odpowiada to czasowi $\frac{-s}{b \cdot ln(1-w)}$ sekund. Wartość $avg$ określa kiedy można wysłać kolejny pakiet. Jeśli $avg \ge 0$, czas kolejnego wysłania ustawiany jest na zero, co oznacza, że klasa jest pod limitem. Jeśli $avg < 0$, czas kolejnego wysłania ustawiany jest o $x$ sekund w przód od czasu aktualnego, gdzie $$\begin{array}{cl} x = -avg \frac{1-w}{w} + f(s,b) &~~~ \textrm{dla klas nieregulowanych} \\ \\ x = f(s,b) &~~~ \textrm{dla klas regulowanych} \end{array}$$ W przypadku klasy nieregulowanej, planista czekając $x$ czasu przed wyslaniem pakietu z tej klasy, będzie miał pewność, że klasa nie pozostanie nad limitem. W przypadku klasy regulowanej, czas wysłania niezależy od średniej ważonej, a więc wcześniejsze wykorzystanie nadmiaru pasma nie umniejsza minimalnego udziału tej klasy w momencie przeciążenia.
Mając ustalone przez estymator czasy kolejnych wysłań, zaimplementowanie planistów jest już prostym zadaniem. Jak już wspomniano podział na planiste generalnego i współdzielącego jest tylko formalny i nie musi mieć odzwierciedlenia w implementacji. Przykładowy algorytm może działać jako planista generalny posługujący się planistą współdzielonym tylko w odpowiednim momencie. Pakiety wysyłane są najpierw z klas o najwyższym priorytecie. Między klasami o jednakowym priorytecie stosuje się algorytm karuzelowy ważony według przydzielonych klasom udziałów. Aby poradzić sobie z klasami o różnych charakterystykach ze względu na wielkości pakietu idealne wydaje się tu zastosowanie wersji deficytowej tego algorytmu.
Zanim jednak planista wyśle pakiet, sprawdza jaki czas wysłania ustawił klasie estymator. Możliwe są 3 przypadki:
Planistę współdzielącego można zaimplementować na dwa sposoby. Pierwszy to modyfikacja czasu wysłania na $f(s,b) = s/b$ sekund od bieżacego momentu – wtedy przy kolejnej rundzie planisty generalnego może okazać się, że klasa nie jest już nad limitem i pakiet zostanie wysłany przez planiste generalnego. Drugi sposób to całkowite wyłączenie klasy z listy algorytmu karuzelowego na czas $f(s,b)$. Nie bieże to jednak pod uwagę możliwości wcześniejszego wysłania pakietu po pozytywnym rozpatrzeniu zasady współdzielenia.
Content by Michał Pokrywka
is licensed under a Creative Commons BY-SA 3.0 Ostatnia znacząca zmiana: 2010-04-28 |