建議搭配 QCN Pseudo Code
QCN 是運用在 L2 環境下的壅塞控制
QCN大致分為 3 部分
- Reaction Point
- Congestion Point
- Reflection Point
對應發送方、中間節點、接收方
Congestion Point
Congestion Point 會在收到封包後計算 $F_b$,$F_b$ 被用來量化壅塞程度
$F_b = (Q_{eq} - q{len}) - W * (q{len} - q{len}_{old})$
$Q_{eq}$ 是 Queue 的參考點,QCN 會將 Queue 長度維持在這裡
W 是控制參數,模擬時取 2
$F_b$ 會被限制在
\[-Q_{eq}*(2*W+1) \le F_b \le 0\]區間內
接下來根據所使用的位元數將 $F_b$ 量化成一個正數稱為 $qntz{F_b}$, 等於 0 時代表沒有壅塞發生。
Congestion Point 會在 Time_to_mark byte counter 小於 0 ,且 $qntz{F_b} > 0$ 時送出 feedback frame
Time_to_mark byte counter小於 0 時還會更新 $q{len}_{old}$ 並更新byte counter
fb_frame 中有
- destination address 送方 MAC
- source address 壅塞點的 MAC
- flow id
- $qntz{F_b}$
- $q_{off}$ $Q_{eq} - q{len}$
- $q_{delta}$ $q{len} - q{len}_{old}$
Reaction Point
在 Reaction Point 第一次收到 feedback 後,會為流啟用一個 rate limiter, rate limiter 中有
- state 區分是否啟用
- flow id
- Crate current rate
- Trate taget rate
- tx_bcount byte counter 用於改變 stage
- si_count 紀錄 byte counter 的 stage
- timer
- timer_scount 紀錄 timer 的 stage
- qlen
如果 fb 不為 0,重設 byte counter 與 timer 的 stage ,並 Multiplicative decrease current rate
\[decfactor = (1 - GD * fb)\] \[Crate = Crate * decfactor\]發送 frame 時,若 Crate 到達速度上限且 qlen 為 0 ,停用 rate limiter。 若不滿足條件,則會讓 tx_bcount 減去 frame 大小。 tx_bcount 倒數結束後,si_count加一,重設 tx_bcount 進入 self_increase 函式
timer 在到期時會將 timer_scount 加一,進入 self_increase 函式,重設timer
byte counter 與 time counter 重設時都是參考 fast recovery threshold,在 stage 大於 threshold 時,expire period 都是原來的一半。
self_increase
首先判斷兩個 timer 的 stage 是否大於 fast recovery threshold,如果其中之一大於 threshold 代表進入 active increase 階段 \(R_i = R_{ai}\)
若兩個都大於,則進入 hyperactive increase 階段
\[R_i = R_{hai} * (min(si\_count,tx\_bcount) - fast recovery threshold)\]若兩個都不大於
\[R_i = 0\]$R_{ai}$ 與 $R_{hai}$ 為控制參數,而 $R_i$ 並不會直接加在 Crate 上,而是加在 Trate 上,而 Crate 最後為
\[Crate = (Crate+Trate)/2\]總結
QCN 有兩個 counter 計算 stage,stage 影響 QCN 所屬階段,Reaction Point 流程圖如下
flowchart TD s[收到 feedback] --> r["reset(si_count timer_count)"] r --> w[等待 counter expire] w -- byte counter expire --> si[self_increase] w -- timer expire --> si si --> sis{"max(si ti)>FRT"} sis --yes-->siss{"min(si ti)>FRT"} sis -- no -->ai[active increase]-->w siss -- yes --> hai[hyperactive increase] siss -- no --> fas[fast recovery] hai --> w fas --> w