多核環境下繫結程序執行在指定的CPU核上

2021-08-02 11:49:46 字數 2864 閱讀 3096

最近做相關演算法效能測試的時候,要測試單核的效能,故需要事先繫結指定的cpu核號。

所謂綁核,其實就是設定某個程序/執行緒與某個cpu核的親和力(affinity)。設定以後,linux排程器就會讓這個程序/執行緒只在所繫結的核上面去執行。但並不是說

該程序/執行緒就獨佔這個cpu的核,其他的程序/執行緒還是可以在這個核上面執行的。如果想要實現某個程序/執行緒獨佔某個核,就要使用cpuset命令去實現。

其實,很多情況下,為了提高效能,linux排程器會自動的實現盡量讓某個程序/執行緒在同樣的cpu上去執行。所以,除非必須,我們沒有必要顯式的去程序綁核操作。

下文介紹兩種繫結的方法:

一、taskset

1.簡單介紹: taskset用來檢視和設定「cpu親和力」,說白了就是檢視或者配置程序和cpu的繫結關係,讓某程序在指定的cpu核上執行,即是「綁核」。

2.taskset的用法

(1)顯示程序執行的cpu

taskset -p pid

注意,此命令返回的是十六進製制的,轉換成二進位制後,每一位對應乙個邏輯cpu,低位是0號cpu,依次類推。如果每個位置上是1,表示該程序繫結了該cpu。例如,0101就表示程序繫結在了0號和3號邏輯cpu上了

(2)綁核設定

a.掩碼形式綁核

按照二進位制形式,從最低位到最高位代表物理cpu的#1、#2、……、#n號核。

比如:0x00000001代表cpu的0號核,0x00000003代表cpu的0號和3號核。

需要注意的是,並非掩碼中給出的cpu核就一定會存在,比如0x00000400理論上代表cpu的第10號核,但是該核在真正的計算機上面並不一定是存在的。而且,如果            我們試圖將物理上並不存的核繫結給某個程序時,會返回錯誤。掩碼形式的綁核命令為:

taskset -p mask pid

b.按cpu數直接綁核

taskset -cp cpu-list pid 或者 taskset -c cpu-list command

其中cpu-list是數位化的cpu列表,從1開始。多個不連續的cpu可用逗號連線,連續的可用短現連線,比如1,2,5-11等。

比如「taskset -c 1,3,5-9 9860」命令表示將程序9860繫結到#1、#3、#5~#9號核上面。

二、sched_setaffinity系統呼叫

乙個cpu的親合力掩碼用乙個cpu_set_t結構體來表示乙個cpu集合,下面的幾個巨集分別對這個掩碼集進行操作:

·cpu_zero() 清空乙個集合

·cpu_set()與cpu_clr()分別對將乙個給定的cpu號加到乙個集合或者從乙個集合中去掉.

·cpu_isset()檢查乙個cpu號是否在這個集合中.

下面兩個函式就是用來設定獲取執行緒cpu親和力狀態: 

·sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask) 

該函式設定程序為pid的這個程序,讓它執行在mask所設定的cpu上.如果pid的值為0,則表示指定的是當前程序,使當前程序執行在mask所設定的那些cpu上.第二個引數cpusetsize是mask所指定的數的長度.通常設定為sizeof(cpu_set_t).如果當前pid所指定的程序此時沒有執行在mask所指定的任意乙個cpu上,則該指定的程序會從其它cpu上遷移到mask的指定的乙個cpu上執行. 

·sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask) 

該函式獲得pid所指示的程序的cpu位掩碼,並將該掩碼返回到mask所指向的結構中.即獲得指定pid當前可以執行在哪些cpu上.同樣,如果pid的值為0.也表示的是當前程序

給出測試**:

#include

#include

#include

#include

#include

#define __use_gnu #include

#include

#include

#include

#define thread_max_num 100 //1個cpu內的最多程序數 int num=0; //cpu中核數 void* threadfun(void* arg) //arg 傳遞執行緒標號 while (1) int i; for (i = 0; i < num; i++) } } return null; } int main(int argc, char* argv) { num = sysconf(_sc_nprocessors_conf); //獲取核數 pthread_t thread[thread_max_num]; printf("system has %i processor(s). \n", num); int tid[thread_max_num]; int i; for(i=0;i

編譯:gcc bind.c -o bind -lpthread

執行:./bind

特別注意:

#define __use_gnu不要寫成#define _use_gnu

#include必須寫在#define __use_gnu之後,否則編譯會報錯

檢視你的執行緒情況可以在執行時在另乙個視窗使用top -h來檢視執行緒的情況,檢視各個核上的情況請使用top命令然後按數字「1」來檢視。

如圖:

讓程序執行在指定的CPU

我的linode十分繁忙,在跑一些密集運算元據庫的rake任務時尤其如此。但我觀察發現,linode伺服器的4核cpu,只有第1個核心 cpu 0 非常忙,其他都處於idle狀態。不了解linux是如何排程的,但在linode的這種狀態下,顯然有優化的餘地。除了處理正常任務,cpu 0還需要處理各種...

linux下讓程序執行在指定的cpu上

最近負責的svr壓力比較大,業務邏輯有點複雜,能優化的地方已經全部優化了,目前每秒3k次,cpu負載還是比較高 top看一下,4核的cpu負載不是太均衡,打算考慮一下將業務程序指定到3個cpu上執行,另外乙個cpu專門負責處理網路收發包 打算嘗試一下,如果還是不行,再過段時間,訪問量再增加的話,就要...

linux下讓程序執行在指定的cpu上

最近負責的svr壓力比較大,業務邏輯有點複雜,能優化的地方已經全部優化了,目前每秒3k次,cpu負載還是比較高 top看一下,4核的cpu負載不是太均衡,打算考慮一下將業務程序指定到3個cpu上執行,另外乙個cpu專門負責處理網路收發包 打算嘗試一下,如果還是不行,再過段時間,訪問量再增加的話,就要...