杜秀芳
【摘要】本文主要介紹了在多核系統(tǒng)中從軟件上開發(fā)的一種CPU優(yōu)化技術(shù)。這種優(yōu)化技術(shù)針對CPU使用不均衡的問題,利用任務調(diào)度算法能自動平衡CPU的使用,提高多核系統(tǒng)中CPU的使用率,從而發(fā)揮CPU的性能優(yōu)勢。
【關(guān)鍵詞】多核系統(tǒng) CPU優(yōu)化 任務調(diào)度
0 引言
隨著CPU技術(shù)的發(fā)展,CPU性能的提高方向已經(jīng)從單核CPU頻率的提高往CPU核數(shù)的提高轉(zhuǎn)變。以INTEL至強系列為例,Xeon D-1521是四核CPU,每核的主頻是2.4GHz;Xeon D-1531處理器是6核設備,主頻是2.2GHz,Xeon E5 v4處理器是10核心設備,主頻是2.2GHzo這三款處理器都是采用14nm工藝制造,主頻并沒有太大分別,在跑分上分別為6980、9730、13923。但是,CPU技術(shù)提高了,應用技術(shù)并沒有很好的配合提高,并不能發(fā)揮CPU的性能優(yōu)勢。本文開發(fā)了一種CPU優(yōu)化技術(shù),可以提高多核系統(tǒng)中CPU的使用率。
1 CPU使用的不均衡問題
在CPU技術(shù)的發(fā)展過程中,核心數(shù)量的增長是近年的趨勢,對于多核支撐,需要程序開發(fā)人員自行分配核心的工作量。但這件事并不是一個簡單的工作,所謂“一核有難十核圍觀”。雖然后來的技術(shù)有一定的改善,但是還是沒有實現(xiàn)均衡的使用。
2 綁核的任務系統(tǒng)
本文開發(fā)了一套任務調(diào)度框架,在本程序框架下運行的程序,會自動平衡多核CPU的使用,達到較優(yōu)的多核使用效率。本框架是在linux環(huán)境下開發(fā)和調(diào)試的,代碼使用C語言。
2.1 action的定義
本框架把每一個要完成的任務定義為一個action。一個action,從業(yè)務上是一個軟件要處理的事務單元,也可以多個事務單元完成一個事務;從代碼上任務可以理解為函數(shù)。以路由器為例,從業(yè)務上,它處理的任務都是I/O相關(guān)的內(nèi)容,所以每個任務包含I/O相關(guān)的信息,比如I/O請求等等;從代碼上,用一個函數(shù)指針來描述任務。由于我們這個任務調(diào)度算法設計的初衷是方便任務調(diào)度、提高CPU使用的效率。所以要求任務的處理時間不能太長。這個太長在CPU領域里面定位為100ms,這個是個估計值。任務的處理時間短是任務的內(nèi)在要求。
當任務的時間過長,會損耗框架的靈活調(diào)度。所以當一個任務的處理時間可能比較長的時候,需要拆分成多個任務,這就是任務拆分。任務拆分的目的是控制單個任務的處理時間。
2.2 線程和CPU的關(guān)系
對于高性能處理器,往往有多個CPU,為了講清楚這個關(guān)系,我們假設CPU的核數(shù)是6核。
在操作系統(tǒng)層面上,基本的運行單元是進程,進程中的調(diào)度單元是線程。一個進程可以有多個線程,但是至少要有一個線程,否則就沒必要存在。對于進程所擁有的資源,線程也是可以共享的。在有了線程的操作系統(tǒng)中,進程是分配資源的基本單元,而線程是獨立運行和獨立調(diào)度的基本單元。相比較進程來講,線程更小,而且不擁有系統(tǒng)資源,所以對線程的調(diào)度開銷會小得多,通過調(diào)度線程可以提高系統(tǒng)的多個程序并發(fā)執(zhí)行的程度。
在配置過程中,一個CPU可以綁定多個線程,即多個線程公用一個CPU。每個線程綁定一個CPU時,系統(tǒng)的性能較高。所以在主程序啟動之初,需要把每個線程跟CPU分別綁定。
2.3 CPU的線程的動卜態(tài)補償
為了適應程序開發(fā)的多樣性,這里任務也分為兩種:一種任務是獨立的,即這種任務可以獨立的運行在一個線程上,不依賴其他的任務,可以獨立完成;另一種任務是非獨立的,即任務之間有相關(guān)性,根據(jù)這個要求,這類任務需要運行在同樣的線程上,以避免共享資源的訪問導致性能下降。獨立的任務跟所在的線程無關(guān),可以運行在任何的線程上;非獨立的任務只能運行在同一個線程上。通常來說,對于大多數(shù)程序開發(fā),獨立的任務占大多數(shù)。
對于非獨立的任務,任務的分配機制是固定的,由使用者自行指定線程(也就是固定線程)。
對于獨立的任務,根據(jù)線程(CPU)的忙碌程度,把任務分配到不太忙碌的線程,實現(xiàn)CPU的均衡配置,這就是任務遷移。
2.4 技術(shù)關(guān)鍵點
實現(xiàn)上,首先要設置進程的CPU數(shù)量,也就是該程序所在進程使用多少個CPU。這里采用的接口是CPU親和度接口族,主要是這幾個接口。
#define_GNU_SOURCE/關(guān)See feature_test_macros(7)*/
int sched_setaffinity(pid_t pid,size_t epusetsize,cpu_set_t*mask);
int sched_getaffinity(pid_t pid,size_t cpusetsize,cpu_set_t*mask);
其中,pid是要CPU的進程pid;mask是二進制掩碼,比如0x000F表示使用CPUO、CPU1、CPU2、CPU3;0x00F1表示使用CPU0、CPU4、CPU5、CPU6、CPU7。
第二個技術(shù)點是要設置線程的CPU關(guān)系,這一點在實現(xiàn)上需要使用線程CPU綁定函數(shù),這里面
int pthread_setaffinity_np(pthread_t thread,size_t epusetsize,const cpu_set_t*cpuset);
int pthread-getaffinity-np(pthread_t thread,size_t cpusetsize,cpu_set_t*cpuset);
其中,thread為線程id; cpusetsize為cpu數(shù)組大小,固定填sizeof(cpu_set_t);cpuset是一個集合,角來表示設置哪些CPU跟這個線程綁定。
這個集合需要提前創(chuàng)建,使用CPU_SEI,接口實現(xiàn)添加。例如:
CPU ZERO(&cpuset;);
for(j=0;i<8;j++)
CPU_SET(j,&cpuset;);
這一段代碼的意思是設置一個CPU包含CPU0-CPU7的集合。
另一個關(guān)鍵點就是要求編程人員能夠?qū)θ蝿者M行劃分,劃分成盡量與線程無關(guān)的任務塊,這樣才能實現(xiàn)任務的自由切換。
3 結(jié)束語
CPU技術(shù)的發(fā)展日新月異,CPU軟件技術(shù)的發(fā)展也是在逐步提高,逐步發(fā)揮出硬件的優(yōu)勢,本文提供了一種在多核設備上從軟件上優(yōu)化CPU的技術(shù)方案。希望能帶給大家一點思路。
參考文獻:
[1]郭建偉.靈活調(diào)度,激活多核CPU“潛力”[J].電腦知識與技術(shù)(經(jīng)驗技巧),2017(11):33-34.