layout | title | subtitle | date | author | header-img | catalog | tags | ||||
---|---|---|---|---|---|---|---|---|---|---|---|
post |
Linux內核25-Per-CPU變量 |
Per-CPU變量的設計思想及使用場景 |
2020-04-02 |
Tupelo Shen |
img/post-bg-unix-linux.jpg |
true |
|
在前面的文章中我們已經學習了內核同步的一些基本概念,爲什麼需要內核同步 其實,最好的同步手段在於設計階段就要儘量避免同步的需求。因爲,畢竟同步的實現都是需要犧牲系統性能的。
既然多核系統中,CPU之間訪問共享數據需要同步,那麼最簡單和有效的同步技術就是爲每個CPU聲明自己的變量,這樣就減少了它們的耦合性,降低了同步的可能性。
使用場景:
一個CPU訪問自己專屬的變量,而無需擔心其它CPU訪問而導致的競態條件。這意味着,per-CPU
變量只能在特定情況下使用,比如把數據進行邏輯劃分,然後分派給各個CPU的時候。
因爲這些per-CPU
變量全部元素都存儲在內存上,所有的數據結構都會落在Cache的不同行上。所以,訪問這些per-CPU
變量不會導致對Cache行進行窺視(snoop)和失效(invalidate)操作,它們都對系統性能有很大的犧牲。
缺點:
-
儘管,
per-CPU
變量保護了來自多個CPU的併發訪問,但是無法阻止異步訪問(比如,中斷處理程序和可延時函數)。這時候,就需要其它同步技術了。 -
此外,不管是單核系統還是多核系統,
per-CPU
變量都易於受到內核搶佔所導致的競態條件的影響。一般來說,內核控制路徑訪問每個CPU變量的時候,應該禁用內核搶佔。假設,內核控制路徑獲得一個per-CPU
變量的拷貝的地址,然後被轉移到其它CPU上運行,這個值就可能會被其它CPU修改。
表5-3 列出了操作per-CPU
變量的函數和宏
函數 | 描述 |
---|---|
DEFINE_PER_CPU(type, name) | 靜態分配一個per-CPU 數組 |
per_cpu(name, cpu) | 選擇元素 |
__get_cpu_var(name) | 選擇元素 |
get_cpu_var(name) | 禁止內核搶佔,選擇元素 |
put_cpu_var(name) | 使能內核搶佔 |
alloc_percpu(type) | 動態分配一個per-CPU 數組 |
free_percpu(pointer) | 釋放動態分配的數組 |
per_cpu_ptr(pointer, cpu) | 返回某個元素的地址 |