0. 前言
不知道有沒有人跟我一樣,看源碼的時候如果想不清一個點總會特别難受,就盯着它不放。
bbr的源碼最開始處就定義了這樣的宏,并寫了注釋,可是我一開始想不通,就是想不通為什麼取這個值,在網上還搜不到相關的解釋。我奇怪這是不是一眼就該看懂的東西,可是我确實就是沒懂吖。糾結之後選擇問我老大,終于給解釋明白了哈哈哈。整理以備忘,也分享給有需要的人。
/* Scale factor for rate in pkt/uSec unit to avoid truncation in bandwidth
* estimation. The rate unit ~= (1500 bytes / 1 usec / 2^24) ~= 715 bps.
* This handles bandwidths from 0.06pps (715bps) to 256Mpps (3Tbps) in a u32.
* Since the minimum window is >=4 packets, the lower bound isn't
* an issue. The upper bound isn't an issue with existing technologies.
*/
#define BW_SCALE 24
#define BW_UNIT (1 << BW_SCALE)
#define BBR_SCALE 8 /* scaling factor for fractions in BBR (e.g. gains) */
#define BBR_UNIT (1 << BBR_SCALE)
1. BW_UNIT
如它的名字所言,它就是一個機關,一個自定義機關,為什麼需要它呢,就是友善表示罷了。比如 0.040s 可以這樣表示,但如果資料都是幾十秒以下的,那這時考慮換成 40ms 來表示會更友善,也不需要浮點數了。這個情況下,機關是熟知的ms,從s過來的縮放因子是1000。
搞清楚這個其實就明白了。我們最終要得到 pkt/uSec 為機關,但實際計算過程當中的資料會長什麼樣呢。定一包資料為1500位元組好了。
1pkt/uSec = 1500B/us = 1500*8b/0.000001s = 1500*8*1000000 bps ~= 12G bps
這時我們就取pkt/uSec為機關的話,1就表示了這個速度了。要知道百兆帶寬的網絡,拉滿了也就100Mbps啊。這個機關顯然對于實際來說還太大了,我們需要更精确的。
如果定2^24為機關的話,那麼 1從表示 12G可以降到 715,即
1500 bytes / 1 usec / 2^24 ~= 715 bps
這時一個u32的數可以表示的範圍從[1,UINT_MAX]變成了 [715, 715*UINT_MAX],也是就是“0.06pps (715bps) to 256Mpps (3Tbps)”。這個範圍對于實際運算來講是合适的,是以可以取這個值。就是說,24隻是一個合适的數,它并不是必須的或者精确的。
2. BBR_UNIT
同理地,BBR_UNIT取的機關值是8,也是為了表示友善而加入縮放因子來調整資料表示範圍。
比如有這樣一個數組 {5/4,3/4,1,1,1,1,1,1 },我們可以選擇定義成一個浮點數的類型來存放這些比例值,也可以選擇加一個縮放因子,比如取4, 然後按這樣子來定義數組,那麼就可以直接用int類型來表示就可以了。
static const int bbr_pacing_gain[] = {
BBR_UNIT * 5 / 4, /* probe for more available bw */
BBR_UNIT * 3 / 4, /* drain queue and/or yield bw to other flows */
BBR_UNIT, BBR_UNIT, BBR_UNIT, /* cruise at 1.0*bw to utilize pipe, */
BBR_UNIT, BBR_UNIT, BBR_UNIT /* without creating excess queue... */
};