在摩爾定律失效以前,提高處理器性能經過主頻提高、硬件超線程等技術就能知足應用須要。隨着主頻提高慢慢接近撞上光速這道牆,摩爾定律開始逐漸失效,多核集成爲處理器性能提高的主流手段。如今市面上已經很難看到單核的處理器,就是這一發展趨勢的佐證。要充分發揮多核豐富的計算資源優點,多核下的並行編程就不可避免,Linux kernel就是一典型的多核並行編程場景。但多核下的並行編程卻挑戰多多。編程
目前主流的計算機都是馮諾依曼架構,即共享內存的計算模型,這種過程計算模型對並行計算並不友好。下圖是一種典型的計算機硬件體系架構。數組
這種架構中,有以下設計特色:緩存
這些硬件體系設計特色也引入不少問題,最大的問題就是cache一致性問題和亂序執行問題。數據結構
cache一致性問題由cache一致性協議MESI解決,MESI由硬件保證,對軟件來講是透明的。MESI協議保證全部CPU對單個cache line中單個變量修改的順序保持一致,但不保證不一樣變量的修改在全部CPU上看到的是相同順序。這就形成了亂序。不只如此,亂序的緣由還有不少:架構
這種狀況形成,就連簡單的++運算操做的原子性都沒法保證。這些問題必須採用多核並行編程新的技術手段來解決。併發
Linux kernel提供了多種鎖機制,如自旋鎖、信號量、互斥量、讀寫鎖、順序鎖等。各類鎖的簡單比較以下,具體實現和使用細節這裏就不展開了,能夠參考《Linux內核設計與實現》等書的相關章節。函數式編程
鎖技術雖然能有效地提供並行執行下的競態保護,但鎖的並行可擴展性不好,沒法充分發揮多核的性能優點。鎖的粒度太粗會限制擴展性,粒度太細會致使巨大的系統開銷,並且設計難度大,容易形成死鎖。除了併發可擴展性差和死鎖外,鎖還會引入不少其餘問題,如鎖驚羣、活鎖、飢餓、不公平鎖、優先級反轉等。不過也有一些技術手段或指導原則能解決或減輕這些問題的風險。函數
原子技術主要是解決cache和內存不一致性和亂序執行對原子訪問的破壞問題。Linux kernel中主要的原子原語有:性能
嚴格來講,Linux kernel做爲系統軟件,實現受硬件影響很大,不一樣硬件有不一樣的內存模型,所以,不一樣於高級語言,Linux kernel的原子原語語義並無一個統一模型。好比在SMP的ARM64 CPU上,barrier、smb_wmb、smb_rmb的實現與smb_mb都是同樣的,都是volatile ("" ::: "memory")。優化
另外,再多提一句的是,atomic_inc()原語爲了保證原子性,須要對cache進行刷新,而緩存行在多核體系下傳播至關耗時,其多核下的並行可擴展性差。
上一小節中所提到的原子技術,是無鎖技術中的一種,除此以外,無鎖技術還包括RCU、Hazard pointer等。值得一提的是,這些無鎖技術都基於內存屏障實現的。
不過,全部的無鎖原語也只能解決讀端的並行可擴展性問題,寫端的並行可擴展性只能經過數據分割技術來解決。
分割數據結構,減小共享數據,是解決並行可擴展性的根本辦法。對分割友好(即並行友好)的數據結構有:
使用這些便於分割的數據結構,有利於咱們經過數據分割來改善並行可擴展性。
除了使用合適的數據結構外,合理的分割指導規則也很重要:
4種分割規則中,全部權分割是分割最完全的。
以上這些多核並行編程內容基本上涵蓋了Linux kernel中全部的併發編程關鍵技術。固然並行編程還有不少其餘技術沒有應用到Linux kernel中的,如無反作用的並行函數式編程技術(Erlang/Go等)、消息傳遞、MapReduce等等。