歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

基於 NUMA 架構的高性能服務器技術(2)

  三、NUMA調度器   NUMA系統中,由於局部內存的訪存延遲低於遠地內存訪存延遲,因此將進程分配到局部內存附近的處理器上可極大優化應用程序的性能。Linux 2.4內核中的調度器由於只設計了一個運行隊列,可擴展性較差,在SMP平台表現一直不理想。當運行的任務數較多時,多個CPU增加了系統資源的競爭,限制了負載的吞吐率。在2.5內核開發時,Ingo Molnar寫了一個多隊列調度器,稱為O(1),從2.5.2開始O(1)調度器已集成到2.5內核版本中。O(1)是多隊列調度器,每個處理器都有一條自己的運行隊列,但由於O(1)調度器不能較好地感知NUMA系統中結點這層結構,從而不能保證在調度後該進程仍運行在同一個結點上,為此,Eirch Focht開發了結點親和的NUMA調度器,它是建立在Ingo Molnar的O(1)調度器基礎上的,Eirch將該調度器向後移植到2.4.X內核中,該調度器最初是為基於IA64的NUMA機器的2.4內核開發的,後來Matt Dobson將它移植到基於X86的NUMA-Q硬件上。     3.1 初始負載平衡     在每個任務創建時都會賦予一個HOME結點(所謂HOME結點,就是該任務獲得最初內存分配的結點),它是當時創建該任務時全系統負載最輕的結點,由於目前Linux中不支持任務的內存從一個結點遷移到另一個結點,因此在該任務的生命期內HOME結點保持不變。一個任務最初的負載平衡工作(也就是選該任務的HOME結點)缺省情況下是由exec()系統調用完成的,也可以由fork()系統調用完成。在任務結構中的node_policy域決定了最初的負載平衡選擇方式。     3.2 動態負載平衡     在結點內,該NUMA調度器如同O(1)調度器一樣。在一個空閒處理器上的動態負載平衡是由每隔1ms的時鐘中斷觸發的,它試圖尋找一個高負載的處理器,並將該處理器上的任務遷移到空閒處理器上。在一個負載較重的結點,則每隔200ms觸發一次。調度器只搜索本結點內的處理器,只有還沒有運行的任務可以從Cache池中移動到其它空閒的處理器。     如果本結點的負載均衡已經非常好,則計算其它結點的負載情況。如果某個結點的負載超過本結點的25%,則選擇該結點進行負載均衡。如果本地結點具有平均的負載,則延遲該結點的任務遷移;如果負載非常差,則延遲的時間非常短,延遲時間長短依賴於系統的拓撲結構。     四、CpuMemSets   SGI的Origin 3000 ccNUMA系統在許多領域得到了廣泛應用,是個非常成功的系統,為了優化Origin 3000的性能,SGI的IRIX操作系統在其上實現了CpuMemSets,通過將應用與CPU和內存的綁定,充分發揮NUMA系統本地訪存的優勢。Linux在NUMA項目中也實現了CpuMemSets,並且在SGI的Altix 3000的服務器中得到實際應用。     CpuMemSets為Linux提供了系統服務和應用在指定CPU上調度和在指定結點上分配內存的機制。CpuMemSets是在已有的Linux調度和資源分配代碼基礎上增加了cpumemmap和cpumemset兩層結構,底層的cpumemmap層提供一個簡單的映射對,主要功能是:將系統的CPU號映射到應用的CPU號、將系統的內存塊號映射到應用的內存塊號;上層的cpumemset層主要功能是:指定一個進程在哪些應用CPU上調度任務、指定內核或虛擬存儲區可分配哪些應用內存塊。     4.1 cpumemmap     內核任務調度和內存分配代碼使用系統號,系統中的CPU和內存塊都有對應的系統號。應用程序使用的CPU號和內存塊號是應用號,它用於指定在cpumemmap中CPU和內存的親和關系。每個進程、每個虛擬內存區和Linux內核都有cpumemmap,這些映射是在fork()、exec()調用或創建虛擬內存區時繼承下來的,具有root權限的進程可以擴展cpumemmap,包括增加系統CPU和內存塊。映射的修改將導致內核調度代碼開始運用新的系統CPU,存儲分配代碼使用新的內存塊分配內存頁,而已在舊塊上分配的內存則不能遷移。Cpumemmap中不允許有空洞,例如,假設cpumemmap的大小為n,則映射的應用號必須從0到n-1。Cpumemmap中系統號和應用號並不是一對一的映射,多個應用號可以映射到同一個系統號。     4.2 cpumemset     系統啟動時,Linux內核創建一個缺省的cpumemmap和cpumemset,在初始的cpumemmap映射和cpumemset中包含系統目前所有的CPU和內存塊信息。     Linux內核只在該任務cpumemset的CPU上調度該任務,並只從該區域的內存列表中選擇內存區分配給用戶虛擬內存區,內核則只從附加到正在執行分配請求CPU的cpumemset內存列表中分配內存。     一個新創建的虛擬內存區是從任務創建的當前cpumemset獲得的,如果附加到一個已存在的虛擬內存區時,情況會復雜些,如內存映射對象和Unix System V的共享內存區可附加到多個進程,也可以多次附加到同一個進程的不同地方。如果被附加到一個已存在的內存區,缺省情況下新的虛擬內存區繼承當前附加進程的cpumemset,如果此時標志位為CMS_SHARE,則新的虛擬內存區鏈接到同一個cpumemset。     當分配頁時,如果該任務運行的CPU在cpumemset中有對應的存儲區,則內核從該CPU的內存列表中選擇,否則從缺省的CPU對應的cpumemset選擇內存列表。     4.3硬分區和CpuMemSets     在一個大的NUMA系統中,用戶往往希望控制一部分CPU和內存給某些特殊的應用。目前主要有兩種技術途徑:硬分區和軟分區技術,CpuMemSets是屬於軟分區技術。將一個大NUMA系統的硬分區技術與大NUMA系統具有的單系統映像優勢是矛盾的,而CpuMemSets允許用戶更加靈活的控制,它可以重疊、劃分系統的CPU和內存,允許多個進程將系統看成一個單系統映像,並且不需要重啟系統,保障某些CPU和內存資源在不同的時間分配給指定的應用。     SGI的CpuMemSets軟分區技術有效解決硬分區中的不足,一個單系統的SGI ProPack Linux服務器可以分成多個不同的系統,每個系統可以有自己的控制台、根文件系統和IP網絡地址。每個軟件定義的CPU組可以看成一個分區,每個分區可以重啟、安裝軟件、關機和更新軟件。分區間通過SGI NUMAlink連接進行通訊,分區間的全局共享內存由XPC和XPMEM內核模塊支持,它允許一個分區的進程訪問另一個分區的物理內存。     五、測試   為了有效驗證Linux NUMA系統的性能和效率,我們在SGI公司上海辦事處測試了NUMA架構對SGI Altix 350性能。     該系統的配置如下:  CPU:8個1.5 GHz Itanium2  內存:8GB  互連結構:如圖3所示     圖3 SGI Altix350 4個計算模塊的Ring拓撲   測試用例:     1、Presta MPI測試包(來自ASCI Purple的Benchmark)  從互連拓撲結構可以看出,計算模塊內部的訪存延遲不需要通過互連,延遲最逗,剩下的需要通過1步或2步互連到達計算模塊,我們通過Presta MPI測試包,重點測試每步互連對系統的影響,具體結果如下:     2、NASA的NPB測試     上述測試表明,SGI Altix 350系統具有較高的訪存和計算性能,Linux NUMA技術已進入實用階段。




Copyright © Linux教程網 All Rights Reserved