最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

一文讀懂進程怎么綁定 CPU(值得收藏)

2022-04-09 20:25 作者:補給站Linux內核  | 我要投稿
  • 首先,我們先來了解下將進程與 CPU 進行綁定的好處。

進程綁定 CPU 的好處:在多核 CPU 結構中,每個核心有各自的L1、L2緩存,而L3緩存是共用的。如果一個進程在核心間來回切換,各個核心的緩存命中率就會受到影響。相反如果進程不管如何調度,都始終可以在一個核心上執(zhí)行,那么其數據的L1、L2 緩存的命中率可以顯著提高。

  • 所以,將進程與 CPU 進行綁定可以提高 CPU 緩存的命中率,從而提高性能。而進程與 CPU 綁定被稱為:CPU 親和性。

設置進程的 CPU 親和性

  • 前面介紹了進程與 CPU 綁定的好處后,現(xiàn)在來介紹一下在 Linux 系統(tǒng)下怎么將進程與 CPU 進行綁定的(也就是設置進程的 CPU 親和性)。


  • Linux 系統(tǒng)提供了一個名為 sched_setaffinity 的系統(tǒng)調用,此系統(tǒng)調用可以設置進程的 CPU 親和性。我們來看看 sched_setaffinity 系統(tǒng)調用的原型:

  • 下面介紹一下 sched_setaffinity 系統(tǒng)調用各個參數的作用:

  1. pid:進程ID,也就是要進行綁定 CPU 的進程ID。

  2. cpusetsize:mask 參數所指向的 CPU 集合的大小。

  3. mask:與進程進行綁定的 CPU 集合(由于一個進程可以綁定到多個 CPU 上運行)。

  • 參數 mask 的類型為 cpu_set_t,而 cpu_set_t 是一個位圖,位圖的每個位表示一個 CPU,如下圖所示:


  • 例如,將 cpu_set_t 的第0位設置為1,表示將進程綁定到 CPU0 上運行,當然我們可以將進程綁定到多個 CPU 上運行。


  • 我們通過一個例子來介紹怎么通過 sched_setaffinity 系統(tǒng)調用來設置進程的 CPU 親和性:


【文章福利】小編推薦自己的Linux內核技術交流群:【891587639】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。?!前100名進群領取,額外贈送一份價值699的內核資料包(含視頻教程、電子書、實戰(zhàn)項目及代碼)?


CPU 親和性實現(xiàn)

  • 知道怎么設置進程的 CPU 親和性后,現(xiàn)在我們來分析一下 Linux 內核是怎樣實現(xiàn) CPU 親和性功能的。

  • 本文使用的 Linux 內核版本為 2.6.23

  • Linux 內核為每個 CPU 定義了一個類型為 struct rq 的 可運行的進程隊列,也就是說,每個 CPU 都擁有一個獨立的可運行進程隊列。


  • 一般來說,CPU 只會從屬于自己的可運行進程隊列中選擇一個進程來運行。也就是說,CPU0 只會從屬于 CPU0 的可運行隊列中選擇一個進程來運行,而絕不會從 CPU1 的可運行隊列中獲取。


  • 所以,從上面的信息中可以分析出,要將進程綁定到某個 CPU 上運行,只需要將進程放置到其所屬的 可運行進程隊列 中即可。


  • 下面我們來分析一下 sched_setaffinity 系統(tǒng)調用的實現(xiàn),sched_setaffinity 系統(tǒng)調用的調用鏈如下:

從上面的調用鏈可以看出,sched_setaffinity 系統(tǒng)調用最終會調用 migrate_task 函數來完成進程與 CPU 進行綁定的工作,我們來分析一下 migrate_task 函數的實現(xiàn):

  • 我們先來介紹一下 migrate_task 函數各個參數的意義:

  1. p:要設置 CPU 親和性的進程描述符。

  2. dest_cpu:綁定的 CPU 編號。

  3. req:進程遷移請求對象(下面會介紹)。

  • 所以,migrate_task 函數的作用就是將進程描述符為 p 的進程綁定到編號為 dest_cpu 的目標 CPU 上。


  • migrate_task 函數主要分兩種情況來將進程綁定到某個 CPU 上:


  • 情況1:如果進程還沒有在任何 CPU 的可運行隊列中(不可運行狀態(tài)),那么只需要將進程描述符的 cpu 字段設置為 dest_cpu 即可。當進程變?yōu)榭蛇\行時,會根據進程描述符的 cpu 字段來自動放置到對應的 CPU 可運行隊列中。

  • 情況2:如果進程已經在某個 CPU 的可運行隊列中,那么需要將進程從之前的 CPU 可運行隊列中遷移到新的 CPU 可運行隊列中。遷移過程由 migration_thread 內核線程完成,migrate_task 函數只是構建一個進程遷移請求,并通知 migration_thread 內核線程有新的遷移請求需要處理。


  • 而進程遷移過程由 __migrate_task 函數完成,我們來看看 __migrate_task 函數的實現(xiàn):

  • __migrate_task 函數主要完成以下兩個工作:

  1. 把進程從原來的可運行隊列中刪除。

  2. 把進程放置到目標可運行隊列中。

  • 其工作過程如下圖所示(將進程從 CPU0 的可運行隊列遷移到 CPU3 的可運行隊列中):


  • 如上圖所示,進程原本在 CPU0 的可運行隊列中,但由于重新將進程綁定到 CPU3,所以需要將進程從 CPU0 的可運行隊列遷移到 CPU3 的可運行中。


  • 遷移過程首先將進程從 CPU0 的可運行隊列中刪除,然后再將進程插入到 CPU3 的可運行隊列中。


  • 當 CPU 要運行進程時,首先從它所屬的可運行隊列中挑選一個進程,并將此進程調度到 CPU 中運行。

總結

  • 從上面的分析可知,其實將進程綁定到某個 CPU 只是將進程放置到 CPU 的可運行隊列中。


  • 由于每個 CPU 都有一個可運行隊列,所以就有可能會出現(xiàn) CPU 間可運行隊列負載不均衡問題。如 CPU0 可運行隊列中的進程比 CPU1 可運行隊列多非常多,從而導致 CPU0 的負載非常高,而 CPU1 負載非常低的情況。


  • 當出現(xiàn)上述情況時,就需要對 CPU 間的可運行隊列進行重平衡操作,有興趣的可以自行閱讀源碼或參考相關資料。



一文讀懂進程怎么綁定 CPU(值得收藏)的評論 (共 條)

分享到微博請遵守國家法律
周宁县| 穆棱市| 祁阳县| 年辖:市辖区| 上思县| 大连市| 兖州市| 固始县| 社旗县| 榆中县| 宝山区| 余江县| 萝北县| 鹤岗市| 赫章县| 修文县| 米脂县| 和平县| 南皮县| 留坝县| 固原市| 闽侯县| 教育| 咸丰县| 兴义市| 邢台市| 丹巴县| 禄丰县| 云浮市| 西充县| 忻城县| 南华县| 叙永县| 昌都县| 年辖:市辖区| 教育| 晋中市| 丘北县| 灌阳县| 临泽县| 德格县|