NGINX原理 之 CPU綁定(CPU親和性)


1 引言

    非統一內存訪問(NUMA)是一種用於多處理器的電腦記憶體設計,內存訪問時間取決於處理器的內存位置。 在NUMA下,處理器訪問它自己的本地存儲器的速度比非本地存儲器(存儲器的地方到另一個處理器之間共享的處理器或存儲器)快一些。

    針對NUMA架構系統的特點,可以通過將進程/線程綁定指定CPU(一個或多個)的方式,提高CPU CACHE的命中率,減少進程/線程遷移CPU造成的內存訪問的時間消耗,從而提高程序的運行效率。[注:關於CPU親和性的概念,可參考《管理處理器的親和性》]


2 源碼剖析

2.1 NGINX源碼

    NGINX進程綁定CPU的代碼非常簡單,其中的核心接口爲sche_setaffinity(),如下所示:


代碼1 綁定CPU

2.2 源碼分析

    經分析可知:

    1) 1進程可綁定到1個或多個CPU核

    -> 如果cpu_affinity的值對應的二進制值爲以下值時,那麼進程將綁定到第7和第63個CPU。(從0開始,下同)

10000000 00000000

00000000 00000000

00000000 00000000

00000000 10000000

    -> 如果cpu_affinity的值對應的二進制值爲以下值時,那麼進程將綁定到第2、第3和第7個CPU。

00000000 00000000

00000000 00000000

00000000 00000000

00000000 10001100

    其他情況可以依此類推。

    2) 該函數可設置CPU核範圍:第0~63個.因爲參數cpu_affinity的類型爲uint64_t,其佔用64位.

2.3 測試實例

    根據NGINX源碼的實現,可以編寫如下測試代碼:

圖1 測試代碼

1) 測試之前:CPU0和CPU1的消耗都很低

圖2 測試之前

2) 綁定CPU0:CPU0的使用接近100%,而CPU1基本不變

圖3 綁定CPU0

2) 綁定CPU1:CPU1的使用接近100%,而CPU0基本不變

圖4 綁定CPU1

2.4 其他接口

    除了sched_setaffinity()可以設置“進程/線程”的CPU親和性外,還可以使用pthread_setaffinity_np()設置“線程”的CPU親和性。參考代碼如下

圖5 線程綁定CPU

    以上代碼對應的Makefile如下:

圖6 Makefile

發佈了66 篇原創文章 · 獲贊 91 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章