跳到主要內容區塊

計資中心電子報C&INC E-paper

技術論壇

多核心計算環境—NUMA與CPUSET簡介
  • 卷期:v0015
  • 出版日期:2010-12-20

作者:周秉誼 / 臺灣大學計算機及資訊網路中心作業管理組碩士後研究人員


多核心處理器的普及化,使得計算環境和軟體及系統設計有了很大的變化。NUMA架構帶來異質的記憶體存取環境,也變成系統管理和使用計憶體的一個挑戰。在了解硬體的NUMA架構後,配合CPUSET功能,適當地分配應用程式或高效能計算工作到特定的處理器上,是一個簡便卻能夠減少記憶體存取時間、提高計算效能的方式。

 

前言

中央處理器 (Central Processing Unit, CPU) 是執行計算程式指令的元件,也是影響計算效能最重要的部份。從1970年代開始,中央處理器的進步速度就像著名的摩爾定理 (Moore’s Law) 所描述,每十八個月處理器中的電晶體數量就會成長一倍,處理器的效能也隨著電晶體數量增加,而能夠用更快的速度進行計算工作。但是,當電晶體的數量成長到一定的規模,處理器龐大的架構和設計的複雜程度也成為增進處理器效率和研發新架構的包袱。為了讓小小的處理器能夠做更多的事情,就產生了另一種想法:為何不在同一個處理器裡放入更多的核心呢,因而出現了多核心處理器 (multi-core processor)。

 

多核心處理器

多核心處理器是指,在同一個處理器的晶片封裝 (chip package) 中放入多個處理器核心 (core),而這些核心在作業系統中都可以被視為是獨立的處理器單元,讓多個程式或執行緒 (thread) 可以同時在不同的核心中進行計算工作。在處理器的架構上,這些核心就是實際在執行計算指令 (instruction) 的部份,在常見的架構中同一個封裝的核心會共享底層的資源,如快取記憶體 (cache),並使用同一個匯流排 (bus) 來與處理器外部溝通。不同架構的多核心處理器也已經被廣泛地使用在各種計算需求的領域,如GPU、DSP、網路路由器、手機及電視遊戲主機等。

 

Intel及AMD等主流個人電腦中央處理器供應商,在時脈提升和能源散熱的問題碰到瓶頸後,也開始推出個人電腦市場的多核心中央處理器。目前市場上最新的Core i7在單一封裝中可以達到6個核心,而更多核心的處理器也在設計當中,在單一電腦中擁有數十個計算核心,也將不是昂貴的大型主機才有的特徵。

 

這樣的進步也造福了高效能運算的使用者,多核心處理器使同樣的機房、機櫃空間中,可以放入更多的計算核心,也可以提供更多的計算能力。以往八個核心的平行計算,要使用兩三台電腦才能進行,還需要呼叫MPI (Message Passing Interface) 的函式庫、透過高速網路才能在不同電腦間同步及資料交換;現在只需要一台具有兩個四核心處理器的電腦就可以完成了,還可以利用共享記憶體 (shared memory) 來進行資料交換,延遲時間 (latency) 比使用gigabit乙太網路快上不少。

 

NUMA架構

然而,就算在同一台電腦中,尤其是有多個處理器的系統,不同核心之間訊息傳遞的速率會有些不同,不同核心存取不同區段記憶體的速率也可能會不一樣。這是因為當系統中的核心數量較多時,原本的對稱式多處理器 (Symmetric Multi-Processor, SMP) 設計,在處理器和記憶體間的匯流排將會成為資料存取的瓶頸,會嚴重地影響到系統效能。NUMA (Non-Uniform Memory Access) 的設計簡化了匯流排的複雜程度,NUMA把系統切成數個節點 (node),每個處理器及記憶體就位在某一個節點上,當處理器存取同一個節點的記憶體時,可以有較高的存取速度;而存取其他節點的記憶體時,就需要透過節點間的資料傳遞,會耗費較多時間。

 

作業系統中為了提高記憶體存取的效率,會針對硬體的NUMA配置來設定記憶體存取的策略 (policy),並提供NUMA相關的程式介面 (API) 來查詢系統NUMA配置和修改存取策略。以GNU Linux為例,作業系統的核心 (kernel) 在2.6版後,就會依據硬體架構的NUMA設計,進行記憶體的配置,並提供NUMA相關的系統呼叫函式 (system call) 供程式使用;在 /proc這個程序虛擬檔案系統 (proc file system) 裡,也有numa_maps檔案可以查詢某個程序 (process) 的記憶體配置。另外也有numactl指令,可以查詢系統的NUMA狀況及改變記憶體配置的策略。

 

因為NUMA架構的影響,當利用共享記憶體進行需要資料交換的平行計算時,如果進行計算的執行緒在不同節點的核心的話,共享記憶體存取的效率就會下降,所以需要了解每個執行緒是被那一個核心所執行。在Linux的環境中,要觀察目前正在執行的程式狀態可以使用top指令,配合-H參數可以顯示所有的執行緒,進入top指令的介面後,打開Last used CPU的資訊,就可以了解每一個執行緒是被那一個核心執行的。參考numactl指令得到的NUMA架構資訊,可以知道每一個核心所屬的節點和每個節點的記憶體配置,利用這些資訊就能規劃執行緒與核心的分配。

 

CPUSET功能

在Linux中要控制每一個程序在那個核心執行,可以使用CPUSET的功能。CPUSET是Linux核心2.6版中的一個小模組,它可以讓使用者將多核心的系統切割成不同區域,每個區域包括了處理器和實體記憶體的區段。使用者可以指定某個程式只能在特定的區域執行,而且該程式不能使用該區域之外的計算資源。一般的應用,如網頁伺服器 (web server)、有多種不同性質程式一同運作的伺服器,或有NUMA架構的高效能運算伺服器,都可以使用CPUSET的功能來增進效率。想確認自己的Linux核心是否有開啟CPUSET功能,可以在/boot下的Linux核心config檔案裡,尋找CONFIG_CPUSET的旗標 (flag) 有沒有開啟。

 

要使用CPUSET來建立區域和調整程序執行位置的其中一個方式,是使用CPUSET虛擬檔案系統 (CPUSET pseudo filesystem)。首先以mount指令將CPUSET檔案系統掛載在/dev/cpuset下,/dev/cpuset這個目錄就代表了整個系統可用的資源,是最基本的一個CPUSET區域。在/dev/cpuset目錄裡可以找到一些檔案,其中cpus檔的內容是在這個CPUSET下可用的處理器編號;mems檔的內容是這個CPUSET下可用的實體記憶體區段;tasks檔的內容是可在這個CPUSET下執行的程序編號 (Process ID, PID)。如果要建立一個新的CPUSET,就在/dev/cpuset下使用mkdir指令建立一個目錄,目錄建立後會自動產生cpus、mems、tasks等檔案。要修改這個CPUSET可用的處理器就用echo指令將處理器編號寫入cpus檔案,要新增程序到這個CPUSET就用echo指令將程序編號寫入tasks檔案。也可以在一個CPUSET下建立多個子集合,進行比較複雜的資源設定。要移除一個CPUSET就用rmdir指令直接移除該CPUSET的目錄就可以了,但是如果該CPUSET中還有程序在進行或還有子集合存在,就沒有辦法移除。

 

CPUSET使用實例

工作排程系統 (job scheduler, batch system, queuing system) 在高效能運算的叢集系統 (cluster) 上,一直扮演很重要的角色,讓計算資源可以公平公正地分享給所有計算工作。而在工作排程系統上使用CPUSET功能,可以讓工作排程系統在多核心的計算環境中,做到更精確地計算資源控制。TORQUE是一套開放原始碼 (open source) 的工作排程系統,它是從PBS (Portable Batch System) 及OpenPBS延伸出來的,廣泛地使用在各種高效能計算領域的資源管理。TORQUE從2.3版之後開始支援Linux 2.6核心的CPUSET,只要在編譯時打開CPUSET功能,就會在後端計算節點開啟CPUSET並自動配置計算資源。當計算節點的TORQUE服務啟動時,就會先在/dev/cpuset建立一個TORQUE的CPUSET;當有計算工作開始進行,TORQUE服務會依據該工作提出的處理器數量需求,建立一個CPUSET子集合,再把該工作的程序都分配到這個CPUSET中。因為被限制在某一個CPUSET中執行,這樣就能防止單一工作佔用其他工作的計算資源。

 

結語

隨著處理器的核心數量一直增加,NUMA架構的計算環境也會更為常見。配合CPUSET能夠有效地控制執行每個應用程式或系統服務的處理器,將會增進系統和計算工作的效能;反之,如果忽略了NUMA架構的特性,會對系統效能有很大的衝擊。例如,VMWare等提供虛擬化 (virtualization) 系統環境的產品,都有針對NUMA架構最佳化的設計和演算法。在個人使用的環境下,想要調效多核心環境的計算效能,Linux核心提供的CPUSET功能會是一個簡單而方便的操作方式。