程序上下文切換 殘酷的效能殺手

2021-07-26 23:13:41 字數 1826 閱讀 9295

對於伺服器的優化,很多人都有自己的經驗和見解,但就我觀察,有兩點常常會被人忽視 – 上下文切換 和 cache line同步 問題,人們往往都會習慣性地把視線集中在盡力減少記憶體拷貝,減少io次數這樣的問題上,不可否認它們一樣重要,但乙個高效能伺服器需要更細緻地去考察這些問題,這個問題我將分成兩篇文章來寫:

1)從一些我們常用的使用者空間函式,到linux核心**的跟蹤,來看乙個上下文切換是如何產生的

2)從實際資料來看它對我們程式的影響 

context switch簡介 -

上下文切換(以下簡稱cs)的定義, 此文中已做了詳細的說明,這裡我又偷懶不詳細解釋了:)  只提煉以下幾個關鍵要點:

*) context(這裡我覺得叫process context更合適)是指cpu暫存器和程式計數器在任何時間點的內容

*)cs可以描述為kernel執行下面的操作

1. 掛起乙個程序,並儲存該程序當時在記憶體中所反映出的狀態

2. 從記憶體中恢復下乙個要執行的程序,恢復該程序原來的狀態到暫存器,返回到其上次暫停的執行**然後繼續執行

*)cs只能發生在核心態(kernel mode)

*)system call會陷入核心態,是user mode => kernel mode的過程,我們稱之為mode switch,但不表明會發生cs(其實mode switch同樣也會做很多和cs一樣的流程,例如通過暫存器傳遞user mode 和 kernel mode之間的一些引數)

*)乙個硬體中斷的產生,也可能導致kernel收到signal後進行cs

什麼樣的操作可能會引起cs -

首先我們一定是希望減少cs,那什麼樣的操作會發生cs呢?也許看了上面的介紹你還雲裡霧裡?

首先,linux中乙個程序的時間片到期,或是有更高優先順序的程序搶占時,是會發生cs的,但這些都是我們應用開發者不可控的。那麼我們不妨更多地從應用開發者(user space)的角度來看這個問題,我們的程序可以主動地向核心申請進行cs,而使用者空間通常有兩種手段能達到這一「目的」:

1)休眠當前程序/執行緒

2)喚醒其他程序/執行緒

pthread庫中的pthread_cond_wait 和 pthread_cond_signal就是很好的例子(雖然是針對執行緒,但linux核心並不區分程序和執行緒,執行緒只是共享了address space和其他資源罷了),pthread_cond_wait負責將當前執行緒掛起並進入休眠,直到條件成立的那一刻,而pthread_cond_signal則是喚醒守候條件的執行緒。我們直接來看它們的**吧

pthread_cond_wait.c

int__pthread_cond_wait (cond, mutex)

pthread_cond_t *cond;

pthread_mutex_t *mutex;

while (val == seq || cond->__data.__woken_seq == val);

/* another thread woken up.  */

++cond->__data.__woken_seq;

bc_out:

/* yunjie: 這裡省略了部分** */

return __pthread_mutex_cond_lock (mutex);}

**已經經過精簡,但我們仍然直接把目光放到19行,lll_futex_wait,這是乙個pthread內部巨集,用處是呼叫系統呼叫sys_futex(futex是一種user mode和kernel mode混合mutex,這裡不展開講了),這個操作會將當前執行緒掛起休眠(馬上我們將會到核心中一**竟)

lll_futex_wait巨集展開的全貌

#define lll_futex_wake(futex, nr, private) 

程序上下文切換 殘酷的效能殺手

對於伺服器的優化,很多人都有自己的經驗和見解,但就我觀察,有兩點常常會被人忽視 上下文切換 和 cache line同步 問題,人們往往都會習慣性地把視線集中在盡力減少記憶體拷貝,減少io次數這樣的問題上,不可否認它們一樣重要,但乙個高效能伺服器需要更細緻地去考察這些問題,這個問題我將分成兩篇文章來...

程序上下文切換 殘酷的效能殺手(下)

幾個月一直懶得沒動筆寫寫部落格,最近開始動筆寫點什麼,今天就趁著加班出版本,橫下心決定把上次爛尾的文章給收了 上篇 接上篇,我們已經通過分析核心 看到pthread cond signal和pthread cond wait會發生cs context switch 本篇我將從實際測試資料出發,來看c...

程序上下文切換 殘酷的效能殺手(下)

幾個月一直懶得沒動筆寫寫部落格,最近開始動筆寫點什麼,今天就趁著加班出版本,橫下心決定把上次爛尾的文章給收了 上篇 接上篇,我們已經通過分析核心 看到pthread cond signal和pthread cond wait會發生cs context switch 本篇我將從實際測試資料出發,來看c...