1. 程式人生 > 其它 >作業系統底層技術——CPU親和性

作業系統底層技術——CPU親和性

頭圖是加拿大lake simcoe自然風光,非常漂亮,基本沒有中國遊客,適合深度遊。

這是作業系統底層技術第二篇,前一篇是《Codegen技術學習

CPU親和性

簡單地說,CPU親和性(affinity)就是程序要在某個給定的CPU上儘量長時間地執行而不被遷移到其他處理器的傾向性。

Linux核心程序排程器天生就具有被稱為軟CPU親和性(affinity)的特性,這意味著程序通常不會在處理器之間頻繁遷移。這種狀態正是我們希望的,因為程序遷移的頻率小就意味著產生的負載小。2.6版本的Linux核心還包含了一種機制,它讓開發人員可以程式設計實現硬CPU親和性(affinity)。這意味著應用程式可以顯式地指定程序在哪個(或哪些)處理器上執行。

原理

什麼是Linux核心硬親和性(affinity)?在Linux核心中,所有的程序都有一個相關的資料結構,稱為task_struct。這個結構非常重要,原因有很多;其中與親和性(affinity)相關度最高的是cpus_allowed位掩碼。這個位掩碼由n位組成,與系統中的n個邏輯處理器一一對應。具有4個物理CPU的系統可以有4位。如果這些CPU都啟用了超執行緒,那麼這個系統就有一個8位的位掩碼。如果為給定的程序設定了給定的位,那麼這個程序就可以在相關的CPU上執行。因此,如果一個程序可以在任何CPU上執行,並且能夠根據需要在處理器之間進行遷移,那麼位掩碼就全是1。實際上,這就是Linux中程序的預設狀態。

Linux核心API提供了一些方法,讓使用者可以修改位掩碼或檢視當前的位掩碼:

   sched_set_affinity()(用來修改位掩碼)
   sched_get_affinity()(用來檢視當前的位掩碼)

注意,cpu_affinity會被傳遞給子執行緒,因此應該適當地呼叫sched_set_affinity。

為什麼應該使用硬親和性(affinity)?通常Linux核心都可以很好地對程序進行排程,在應該執行的地方執行程序(這就是說,在可用的處理器上執行並獲得很好的整體效能)。核心包含了一些用來檢測CPU之間任務負載遷移的演算法,可以啟用程序遷移來降低繁忙的處理器的壓力。

一般情況下,在應用程式中只需使用預設的排程器行為。然而,您可能會希望修改這些預設行為以實現效能的優化。讓我們來看一下使用硬親和性(affinity)的2個原因。

原因1.充分利用cpu cache

如果一個給定的程序遷移到其他地方去了,那麼它就失去了利用CPU快取的優勢。實際上,如果正在使用的CPU需要為自己快取一些特殊的資料,那麼所有其他CPU都會使這些資料在自己的快取中失效。

因此,如果有多個執行緒都需要相同的資料,那麼將這些執行緒繫結到一個特定的CPU上是非常有意義的,這樣就確保它們可以訪問相同的快取資料(或者至少可以提高快取的命中率)。否則,這些執行緒可能會在不同的CPU上執行,這樣會頻繁地使其他快取項失效。

原因2保障時間敏感的、決定性的程序的cpu利用

我們對CPU親和性(affinity)感興趣的最後一個原因是實時(對時間敏感的)程序。例如,您可能會希望使用硬親和性(affinity)來指定一個8路主機上的某個處理器,而同時允許其他7個處理器處理所有普通的系統排程。這種做法確保長時間執行、對時間敏感的應用程式可以得到執行,同時可以允許其他應用程式獨佔其餘的計算資源。

應用場景

使用cpu親和技術會顯著提高cpu利用率,但是同時帶來的副作用是喪失程式的擴充套件性,應用程式需要單獨設定。這項技術在一些需要高效能,軟硬結合的場景下非常有效。

雲的核心技術就是虛擬化技術,首先是虛擬化技術,Cpu親和技術在雲上因此失效。