per-CPU(未完待續)

簡介

  • per-CPU變量是內核的一個重要機制,正如名稱所示,per-CPU變量爲每個cpu單獨提供內存空間,每個cpu只訪問修改各自的空間
  • 一個per-CPU變量所需要的內存大小爲:變量類型大小乘以cpu數量,即sizeof(type) x (number of cpus)
    • 在NUMA系統中,計算所佔內存大小的公式與上面類似,但是實際上cpu數量的計算更復雜
  • 事實上,不管哪一種同步API都會帶來或多或少的性能開銷,但是一個per-CPU數據包含每個cpu自己的唯一私有數據,一個cpu不應該訪問其他cpu對應的數據,所以按照這樣邏輯不再需要使用同步API。注意:“只有這個cpu能訪問這個數據“就是一種編程約定,我們需要確保當前cpu只會訪問它自己的唯一數據。
  • 很多內核子系統使用了這個機制:
    • 內存管理的高速緩存機制
      • Page分配器
      • SLUB/SLAB分配器
    • 經常需要更新的性能統計計數器,需要高效同步機制的例子
      • vm統計
      • 網絡統計
    • 基礎設施RCU
    • 性能剖析profiling、Ftrace
    • VFS虛擬文件系統

下圖是一個簡單的per-CPU計數器例子
這裏寫圖片描述

特點

Unit

  • 每個cpu數據將放入每個cpu對應的unit內存空間
  • unit不僅可能包含三種不同類型的內存區域,也有可能只包含一種內存區域
    • Static內存區域
      • 使用DEFINE_PER_CPU()宏聲明per-CPU變量,其被編譯進kernel映像中,在系統啓動時爲每個cpu定義這個變量
      • 默認大小0x3ec0
    • Reserved內存區域
      • 使用DEDINE_PER_CPU()宏聲明per-CPU變量,其被編譯進模塊文件中,在加載模塊時爲每個cpu定義這個變量
      • 默認大小0x2000(8KiB)
    • Dynamic 內存區域
      • 藉助alloc_percpu函數動態地分配每個cpu變量所佔的內存空間
      • 默認大小0x5000(20KiB)
        • 在64位系統上,默認大小28KiB
  • unit大小等於
    • pcpu_unit_pages
      • 組成一個Unit的頁幀數
      • 通常大小爲 16
    • pcpu_unit_szie
      • 組成一個Unit的字節大小(單位Byte)
      • 通常大小爲 0x10000(64KiB = 16 * 4KiB (PAGE_SIZE))

這裏寫圖片描述

這裏寫圖片描述

CPU -> Unit 映射

下圖是一個在NUMA系統中cpu與unit映射的例子,(這個NUMA系統最大支持32CPU,實際有12CPU可用)
這裏寫圖片描述

Chunk

per-CPU機制初始化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章