首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 內核閱讀筆記:likely/unlikely 優化、TSO/UFO/GSO/LRO/GRO/RSS 網絡協議棧技術解析

     編輯:關於C語言

一、`likely()` / `unlikely()` 編譯器提示

定義與原理

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
  • GCC/Clang 內建函數 `__builtin_expect(expr, expected)`
  • 告訴編譯器 `expr` 為真/假的概率預期
  • 編譯器據此調整分支預測、指令排序、基本塊佈局

實際效果

// 熱路徑:預期成功
if (likely(ptr != NULL)) {
    // 編譯器將此基本塊放在直線執行路徑,無跳轉
    process(ptr);
} else {
    // 冷路徑:放在遠處,可能需跳轉
    handle_error();
}

// 錯誤處理:預期失敗
if (unlikely(ret < 0)) {
    return ret;  // 罕見路徑,不污染熱路徑指令緩存
}

使用準則

  1. 僅用於性能熱點(每秒百萬次調用的路徑)
  2. 2. 基於測量數據(perf、tracepoint),而非直覺 3. 避免濫用:錯誤預期反而降低性能(分支預測器誤導) 4. 內核風格:`if (unlikely(!ptr)) return -ENOMEM;` 守衛模式常見

參考資源

  • Linux 內核源碼:`include/linux/compiler.h`
  • 文檔:`Documentation/process/deprecated.rst` (關於 `__builtin_expect` 現代替代)
  • 博客:likely/unlikely 詳細解析

二、網絡協議棧大規模傳輸優化技術族系

核心問題:CPU 處理網絡封包開銷過大

  • 傳統路徑:每個小封包(~1.5KB)需完整協議棧處理 → 系統調用、中斷、緩衝區拷貝、校驗和計算
  • 高速網卡(10G/25G/100G)下,CPU 成為瓶頸

技術演進脈絡

1. TSO (TCP Segmentation Offload) — 發送端大分段卸載

  • 應用層寫入大緩衝區(如 64KB)
  • 網卡硬體負責按 MSS 分段、添加 TCP/IP 頭部、校驗和計算
  • CPU 僅處理一次大緩衝區,系統調用/中斷減少 40 倍

2. UFO (UDP Fragmentation Offload) — UDP 分片卸載

  • TSO 的 UDP 版本,大 UDP 數據報由網卡分片
  • 較少見,因 UDP 無連接、應用層常自行控制分片

3. GSO (Generic Segmentation Offload) — 通用分段卸載(軟件兜底)

  • 網卡不支援 TSO 時,內核在發送隊列中用軟件模擬分段
  • 2. 仍可合併多個 `skb` 分配/頭部構建,減少協議棧遍歷次數 3. `skb_gso_segment()` 核心函數

4. LRO (Large Receive Offload) — 接收端大封包合併(硬體)

  • 網卡將同一 TCP 連接的多個小封包合併為大封包再上傳內核
  • 風險:合併後時間戳、SACK、窗口資訊可能失真,影響擁塞控制
  • 現代內核傾向關閉 LRO,改用 GRO

5. GRO (Generic Receive Offload) — 通用接收卸載(軟件,內核主導)

  • 在網卡驅動/內核協議棧入口(`napi_gro_receive`)合併封包
  • 比 LRO 更智能:保留關鍵 TCP 選項、支援多隊列、可被協議棧感知
  • 目前 Linux 默認開啟,`ethtool -k eth0 gro on`

6. RSS (Receive Side Scaling) — 接收端縮放(多隊列分發)

  • 網卡多個 RX 隊列,按雜湊(源/目的 IP/端口)分發到不同 CPU 核心
  • 解決單核處理中斷瓶頸,實現網絡處理多核並行
  • 配合 RPS/RFS(軟件模擬 RSS)用於無硬體 RSS 的網卡

技術對比總結表

技術方向層級核心作用現狀
TSOTX硬體大分段卸載標配
UFOTX硬體UDP 分片卸載較少用
GSOTX軟件TSO 軟件兜底默認開
LRORX硬體大封包合併建議關
GRORX軟件智能合併默認開
RSSRX硬體多隊列分發標配

內核關鍵代碼路徑

  • TSO/GSO:`net/core/dev.c` → `dev_hard_start_xmit()` → `skb_gso_segment()`
  • GRO:`net/core/gro.c` → `napi_gro_receive()` → `gro_receive()`
  • RSS:驅動 `ndo_select_queue` + `ethtool -X` 配置雜湊鍵

調試與觀測命令

# 查看網卡卸載能力
ethtool -k eth0 | grep -E 'tcp-segmentation|generic-segmentation|large-receive|generic-receive|receive-hashing'

# 動態開關
ethtool -K eth0 tso on gso on gro on lro off rxhash on

# 觀測統計
ethtool -S eth0 | grep -i 'tso\|gro\|lro\|rss'

參考資源

總結

`likely/unlikely` 是編譯器層面的分支預測提示,適用於極熱路徑;TSO/GSO/GRO/RSS 族系是網絡數據平面的大規模並行化技術棧,核心思想是批量處理、硬體卸載、多核分發。閱讀內核網絡子系統時,建議從 `net/core/dev.c` 發送路徑、`net/core/gro.c` 接收路徑、驅動 `ndo_select_queue` 入手,結合 `ethtool` 實機觀測,形成「代碼-配置-觀測」閉環理解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved