
我不明白為什麼tcp_adv_win_scale
和 tcp_app_win
變數在 Linux 中共存。訊息來自TCP(7)說:
為了tcp_adv_win_scale
:
tcp_adv_win_scale
(整數;預設值:2;自 Linux 2.4 起)
將緩衝開銷計算為
bytes/2^tcp_adv_win_scale
, 如果tcp_adv_win_scale
大於0;或者bytes-bytes/2^(-tcp_adv_win_scale)
, 如果tcp_adv_win_scale
小於或等於零。套接字接收緩衝區空間在應用程式和核心之間共用。 TCP維護部分緩衝區作為TCP窗口,這是通告給另一端的接收窗口的大小。其餘空間用作“應用程式”緩衝區,用於將網路與調度和應用程式延遲隔離。這
tcp_adv_win_scale
預設值 2 表示用於應用程式緩衝區的空間是總空間的四分之一。
對於tcp_app_win
:
tcp_app_win
(整數;預設值:31;自 Linux 2.4 起)此變數定義為緩衝開銷保留 TCP 視窗的位元組數。
最多為 (
window/2^tcp_app_win
, mss) 視窗中的位元組保留給應用程式緩衝區。值 0 表示沒有保留任何金額。
所以我不確定tcp_app_win
到底改變了什麼。在我看來,這兩個變數都可以用來調整 TCP 應用程式緩衝區,因此不需要一起更改它們。我說得對嗎?
答案1
我找到了這個信息,其中談到了tcp_adv_win_scale
。該頁面的標題是:TCP效能調優-如何調優linux。
摘抄
TCP 效能受到延遲和視窗大小(以及開銷,這會減少有效視窗大小)的限制,具體取決於 window_size/RTT(這是在任何給定時刻可以透過連結「傳輸」的資料量)。
要獲得可能的實際傳輸速度,您必須將結果視窗除以延遲(以秒為單位):
開銷為:window/2^tcp_adv_win_scale(tcp_adv_win_scale預設為2)
因此,對於 Linux 接收視窗 (tcp_rmem) 的預設參數:87380 - (87380 / 2^2) = 65536。
給定跨大西洋鏈路(150 ms RTT),最大效能最終為:65536/0.150 = 436906 位元組/秒或約 400 kbyte/秒,這在今天確實很慢。
隨著預設大小的增加:(873800 - 873800/2^2)/0.150 = 4369000 位元組/秒,或大約 4Mbytes/秒,這對於現代網路來說是合理的。請注意,這是預設設置,如果發送方配置了更大的視窗大小,它會很高興地擴展到 10 倍(8738000*0.75/0.150 = ~40Mbytes/s),這對於現代網路來說非常好。
2.6.17 及更高版本具有相當好的預設值,如果對方支援的話,實際上可以將視窗大小調整到允許的最大值。因此,從那時起,本指南的大部分內容就不再需要了。不過,為了獲得良好的長途吞吐量,可能需要增加最大值。
我能夠理解這一點,但不太理解這兩個變數之間的關係(如果有的話)。
我只是勉強理解這試圖解釋什麼。從本質上講,這個參數聽起來像是用於縮放 TCP 和應用程式的緩衝空間量。
經過更多搜索,我發現這些解釋更有意義。該頁面的標題是:Ipsysctl 教學 1.0.4 - 第 3 章 IPv4 變數引用。
摘抄
3.3.2. tcp_adv_win_scale
此變數用於告訴核心應將多少套接字緩衝區空間用於 TCP 視窗大小,以及為應用程式緩衝區保存多少空間。如果 tcp_adv_win_scale 為負數,則使用下列公式計算視窗縮放的緩衝區開銷:
其中 bytes 是視窗中的位元組數。如果 tcp_adv_win_scale 值為正,則使用下列公式計算緩衝區開銷:
tcp_adv_win_scale 變數採用整數值,預設為 2。
3.3.3. tcp_app_win
此變數告訴核心在傳輸特定 TCP 視窗的 TCP 套接字記憶體緩衝區中為特定 TCP 視窗保留多少位元組。
從上面的計算中您可能會了解到,該值越大,特定視窗的緩衝區空間就越小。此計算的唯一例外是 0,它告訴核心不為該特定連接保留空間。該變數的預設值為 31,通常應該是一個不錯的值。除非您知道自己在做什麼,否則請勿變更此值。
根據這些解釋,聽起來第一個參數tcp_adv_win_scale
是控制套接字緩衝區空間的分割,即如何劃分 TCP 視窗使用與應用程式緩衝區。
而第二個參數tcp_app_win
指定為描述中提到的應用程式緩衝區保留的位元組數tcp_adv_win_scale
。
答案2
以下是我從內核原始碼中得到的發現:
- tcp_adv_win_scale 用於宏include/net/tcp.h 中的 tcp_win_from_space。此巨集用於net/ipv4/tcp_input.c 中的函數 tcp_grow_window。
似乎它僅用於已建立的連接,而不用於連接。
此參數的預設值為 1,這會導致應用程式使用 50% 的 rcv 緩衝區。 - tcp_app_win 用於net/ipv4/tcp_input.c 中的函式 tcp_init_buffer_space。
似乎它僅用於連接而不用於已建立的連接。
此參數的預設值為 31,這會導致應用程式使用 0.0% 的 rcv 緩衝區。
我想說的邏輯不是為新連接中的應用程式保留緩衝區並在接收資料時增加它。
這樣理論上初始 rwnd 可以被廣告為與整個緩衝區一樣大。發送方將發送那麼多資料。接收器緩衝區將會填滿,接收器將根據 tcp_adv_win_scale 縮小 win 並增加緩衝區的應用部分。
所以,如同中所提到的@slm答案 - 似乎沒有理由接觸 tcp_app_win。