昨天說今天要換封包長度,看時戳是打在 frame 的開頭還是結尾。
先講我原本怎麼想 : 一個 64 bytes 的封包推上 10G 的線要 51.2 奈秒,1518 bytes 要 1214.4 奈秒,差 1163 奈秒。這叫序列化,就是把資料一個 bit 一個 bit 推出去所花的時間算出來。所以我以為封包變長,量到的延遲就會跟著往上爬。
64 到 1518 掃過去,六個長度,每個五千筆:

中位數一奈秒都沒動。我以為會冒出來的那 1163 奈秒,完全沒有出現。
它其實一直都在,只是沒有進到我量的這個數字裡。
原因是兩個時戳打在 frame 的同一個位置。以這張卡來說是打在開頭:網卡在第一個 bit 出去的瞬間擷取一個 TX 時戳,接收端在第一個 bit 進來的瞬間擷取一個 RX 時戳,兩邊都還沒開始推資料就把時間記下來了,所以中間那段在相減的時候就抵消掉。
兩個時戳打在同一個位置 -> 序列化相減的時候被抵消掉,跟封包多長無關
一邊開頭、一邊結尾 -> 相減之後會多出整段序列化,封包越長數字越大
這六個一模一樣的 60.0,證明的是兩個時戳打在 frame 的同一個位置,序列化在相減的時候被抵消掉了。嚴格講,兩邊都打在結尾也會是平的,這組數據分不出開頭還是結尾。不過對後面要做的事來說這樣就夠了,我要的是一把量出來不隨封包長度變的尺。昨天那篇只有 64 bytes 一種長度,連這個都分不出來;今天換了長度,答案就自己跳出來了。
所以這件事就得用這個角度看:它量的不是「這個封包花多久跑完」,是「這個封包的頭花多久到對面」。 兩件事在低延遲的世界裡差很多,而且後面每一個數字都建立在這個理解上。
直連量到的 60 奈秒裡沒有任何網路,那是網卡自己收發一個封包、加上中間那條線的時間。**它不是誤差,是一個要被扣掉的已知量。**那條線我用三條不同長度同型號 DAC Cable 各量一次:

相鄰相減分別是 4.99 跟 4.94,所以每多一公尺大約 4.96 奈秒。三個點拉一條直線,最大殘差 0.01 奈秒。
反推回去,線長等於零的時候是 46 奈秒左右,那就是網卡自己的收發路徑。所以三公尺那次的平均 61 奈秒裡,46 是網卡的,剩下 15 是那三公尺線。(這裡用平均不用中位數,下一節就是在講這個。)
4.96 這個數字還可以再驗一次。光在真空裡一公尺要 3.34 奈秒,除下來:
3.34 ÷ 4.96 ≈ 0.67
訊號在這條銅纜裡跑光速的三分之二。 這個數字落在銅纜該有的範圍裡,所以那條擬合線不是湊出來的。
這裡有個一定要講的前提:三條線必須是同型號。 不同型號的線每公尺差多少本來就不一樣,混著量的斜率就沒有意義。而且量出來的 4.96 只能用在這一批線上,換一批就要重量。
上面那三個是平均值。同一次量測還有三個中位數,長這樣:
1 公尺 平均 51.12 ns 中位數 52.0 ns
2 公尺 平均 56.11 ns 中位數 56.0 ns
3 公尺 平均 61.05 ns 中位數 60.0 ns
中位數那一欄是 52、56、60,每格剛好差 4.0。 拿它拉同一條線,斜率會是漂亮的 4.000 ns/m。
平均值算出來是 4.96。差了將近兩成。
原因是 Day 3 講過的那件事:硬體時戳只會落在 4 奈秒的格線上,所以中位數永遠是某一條格線,它沒辦法表達格與格之間的位置。而這三個點從頭到尾只跨了 9 奈秒多,也就是兩格多一點,所以要在只有兩格的跨距上拉斜率,中位數能給的答案本來就只有 4 的倍數。
平均值不一樣。一萬筆各自落在哪條格線上,平均之後那個小數點就把「其實偏哪一邊」還原出來了。
同樣一條 3 公尺的線:
用 4.000 算 -> 線材佔 12.0 ns
用 4.96 算 -> 線材佔 14.9 ns
差快三奈秒,而我整天在量的東西是幾十奈秒。
所以這篇兩種統計量混著用是刻意的,不是隨便挑。
要拉斜率、要算每公尺多少 -> 用平均值
要判斷「今天跟上次一樣嗎」 -> 用中位數
中位數對後者反而更好用,因為它不會被幾個離群值拉走。選哪一種,看你要問的是什麼問題,不是看哪一個比較常見。
Day 3 說過「每次要量之前先跑一次直連」。今天可以講得更具體。
門檻是中位數必須等於 60.0。 這個 60.0 是我這條 3 公尺線的,上面那三個中位數裡 1 公尺是 52.0、2 公尺是 56.0,換線就要換數字。
這條看起來很嚴,但我有實測結果:同一條線隔四天前後量了十二次,每次五千筆,十二次的中位數全部是 60.0。不過中位數只有 4 奈秒的解析度,這句話其實只說得出「四天內沒有動超過一格」。用平均值才看得見更細的那一段:隔一天重量,差 0.12 奈秒。所以「不是 60.0」本身就是訊號,不需要再訂什麼容許帶。
既然它自己不會漂,那就不該綁時間跑,要綁事件跑。
量正式數據之前 -> 必跑
換線、拔插光模組、換 port -> 必跑
主機重開機之後 -> 必跑
沒人動過的期間 -> 每週一次就夠
前三條是因為那些動作直接改變被量的東西。最後那條是為了抓「有人動過但沒講」的情況。
還有一件事分享:這個要讓機器跑,不要讓人跑
人會忘記,也很難每次都用同一組參數。更常見的是前置設定沒開就開始量,跑完才發現整組要重來。前後兩次要比得起來,條件就得一模一樣,而「一模一樣」這件事人很難做到,只有把參數寫死在設定檔裡的腳本做得到。
這也是為什麼校正值要連同當次的條件一起存:線材幾公尺、封包幾個、哪種模式。三個月後翻出一個 60.0,你要知道它是在什麼條件下量的,不然它就只是一個數字。
明天我會回到交換器,用今天校好的基準,量它轉發一個封包要多久。