每 CPU 的變數

2021-06-18 00:21:29 字數 2248 閱讀 6442

每-cpu 變數是乙個有趣的 2.6 核心的特性. 當你建立乙個每-cpu變數, 系統中每個處理器獲得它自己的這個變數拷貝. 這個可能象乙個想做的奇怪的事情, 但是它有自己的優點. 訪問每-cpu變數不需要(幾乎)加鎖, 因為每個處理器使用它自己的拷貝. 每-cpu 變數也可存在於它們各自的處理器快取中, 這樣對於頻繁更新的量子帶來了顯著的更好效能.

乙個每-cpu變數的好的使用例子可在網路子系統中找到. 核心維護無結尾的計數器來跟蹤有每種報文型別有多少被接收; 這些計數器可能每秒幾千次地被更新. 不去處理快取和加鎖問題, 網路開發者將統計計數器放進每-cpu變數. 現在更新是無鎖並且快的. 在很少的機會使用者空間請求看到計數器的值, 相加每個處理器的版本並且返回總數是乙個簡單的事情.

每-cpu變數的宣告可在 中找到. 為在編譯時間建立乙個每-cpu變數, 使用這個巨集定義:

define_per_cpu(type, name);
如果這個變數(稱為 name 的)是乙個陣列, 包含這個型別的維數資訊. 因此, 乙個有 3 個整數的每-cpu 陣列應當被建立使用:

define_per_cpu(int[3], my_percpu_array);
每-cpu變數幾乎不必使用明確的加鎖來操作. 記住 2.6 核心是可搶占的; 對於乙個處理器, 在修改乙個每-cpu變數的臨界區中不應當被搶占. 並且如果你的程序在對乙個每-cpu變數訪問時將, 要被移動到另乙個處理器上, 也不好. 因為這個原因, 你必須顯式使用 get_cpu_var 巨集來訪問當預處理器的給定變數拷貝, 並且當你完成時呼叫 put_cpu_var. 對 get_cpu_var 的呼叫返回乙個 lvalue 給當預處理器的變數版本並且禁止搶占. 因為乙個 lvalue 被返回, 它可被賦值給或者直接操作. 例如, 乙個網路**中的計數器時使用這 2 個語句來遞增的:

get_cpu_var(sockets_in_use)++;

put_cpu_var(sockets_in_use);

你可以訪問另乙個處理器的變數拷貝, 使用:

per_cpu(variable, int cpu_id);
如果你編寫使處理器涉及到對方的每-cpu變數的**, 你, 當然, 一定要實現乙個加鎖機制來使訪問安全.

動態分配每-cpu變數也是可能的. 這些變數可被分配, 使用:

void *alloc_percpu(type);

void *__alloc_percpu(size_t size, size_t align);

在大部分情況, alloc_percpu 做的不錯; 你可以呼叫 __alloc_percpu 在需要乙個特別的對齊的情況下. 在任一情況下, 乙個 每-cpu 變數可以使用 free_percpu 被返回給系統. 訪問乙個動態分配的每-cpu變數通過 per_cpu_ptr 來完成:

per_cpu_ptr(void *per_cpu_var, int cpu_id);
這個巨集返回乙個指標指向 per_cpu_var 對應於給定 cpu_id 的版本. 如果你在簡單地讀另乙個 cpu 的這個變數的版本, 你可以解引用這個指標並且用它來完成. 如果, 但是, 你在操作當預處理器的版本, 你可能需要首先保證你不能被移出那個處理器. 如果你訪問這個每-cpu變數的全部都持有乙個自旋鎖, 萬事大吉. 常常, 但是, 你需要使用 get_cpu 來阻止在使用變數時的搶占. 因此, 使用動態每-cpu變數的**會看來如此:

int cpu; 

cpu = get_cpu()

ptr = per_cpu_ptr(per_cpu_var, cpu);

/* work with ptr */

put_cpu();

當使用編譯時每-cpu 變數時, get_cpu_var 和 put_cpu_var 巨集來照看這些細節. 動態每-cpu變數需要更多的顯式的保護.

每-cpu變數能夠輸出給每個模組, 但是你必須使用乙個特殊的巨集版本:

export_per_cpu_symbol(per_cpu_var);

export_per_cpu_symbol_gpl(per_cpu_var);

為在乙個模組記憶體取這樣乙個變數, 宣告它, 使用:

declare_per_cpu(type, name);
declare_per_cpu 的使用(不是 define_per_cpu)告知編譯器進行乙個外部引用.

如果你想使用每-cpu變數來建立乙個簡單的整數計數器, 看一下在 中的現成的實現. 最後, 注意一些體系有有限數量的位址空間變數給每-cpu變數. 如果你建立每-cpu變數在你自己的**, 你應當盡量使它們小.

每 CPU 的變數

每 cpu 變數是乙個有趣的 2.6 核心的特性.當你建立乙個每 cpu變數,系統中每個處理器獲得它自己的這個變數拷貝.這個可能象乙個想做的奇怪的事情,但是它有自己的優點.訪問每 cpu變數不需要 幾乎 加鎖,因為每個處理器使用它自己的拷貝.每 cpu 變數也可存在於它們各自的處理器快取中,這樣對於...

linux核心中的每cpu變數

摘自 一 linux中的每cpu變數 看linux核心 的時候,會發現大量的per cpu name,cpu get cpu var name 等出現cpu字眼的語句。從語句的意思可以看出是要使用與當前cpu相關的乙個變數,不過檢視這個變數的定義,總是有這樣乙個巨集 define per cpu t...

linux核心中的每cpu變數

一 linux中的每cpu變數 看linux核心 的時候,會發現大量的per cpu name,cpu get cpu var name 等出現cpu字眼的語句。從語句的意思可以看出是要使用與當前cpu相關的乙個變數,不過檢視這個變數的定義,總是有這樣乙個巨集 define per cpu type...