愛伊米

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

作者 |hoakley 譯者 | 彎月

出品 | CSDN(ID:CSDNnews)

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

在傳統的多核心處理器中(比如之前Mac型號使用的英特爾CPU),所有的核心都是相同的。將執行緒分配給核心時,只需要平衡它們的負載即可,這種方式叫做對稱式多處理(symmetric multiprocessing,SMP)。

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

在活動監視器的“CPU歷史”視窗中,核心負載(即CPU%)是根據時間顯示的,最早的值顯示在最左側。左半邊奇數序號的核心是真實的核心,顯示了一個8核心英特爾至強W在大負載下的情況。右側的偶數序號的核心是超執行緒模擬的虛擬核心,也負責處理大負載。

但蘋果晶片的CPU不一樣,因為它包含兩種不同的核心型別,一種用於高效能(稱為效能核心、P核心或Firestorm核心),另一種用於低功耗(稱為效率核心、E核心或Icestorm核心)。為了提高效率,執行緒需要根據核心型別進行分配。這個分配工作可以由應用程式和程序自己控制,比如Asahi Linux;也可以由作業系統負責,比如macOS。在本文中,我們就來看一看macOS是如何管理蘋果M1晶片上的核心分配的。這種管理方式叫做非對稱式多處理(AMP,不過有人喜歡叫它異質計算)。

架構

M1系列晶片的CPU核心有兩種:

E核心,其內部處理單元大約為P核心的一半,最大時鐘頻率為2064MHz。

P核心,擁有更高的最大頻率,原始M1為3204MHz,M1 Pro/Max/Ultra為3228MHz。

M1系列晶片的CPU核心配置方式有三種:

原始M1包含4個E和4個P核心,用於MacBook Air、13寸MacBook Pro、iMac和Mac mini

M1 Pro和Max有2個E和8個P核心,用於14寸和16寸MacBook Pro和Mac Studio Max。

M1 Ultra有4個E和16個P核心,用於Mac Studio Ultra。

一些14寸MacBook Pro筆記本使用了縮水版的M1 Pro晶片,其P核心數量從8個降為6個。

為了簡化核心管理,macOS按照功能將核心分成簇,每個簇包含2~4個同類型的核心。可惜,系統級別的核心編號(如powermetrics等工具顯示的核心編號)和活動監視器中看到的核心編號是不一樣的。為了與後者一致,此處我們採用了活動監視器中看到的核心編號,但簇的編號還是與系統的方式一致。在macOS Monterey 12。3。1中,三個晶片的功能簇如下:

原始的M1中,每種型別的核心只有一個簇,分別為E0和P0,每個簇包含同一型別的4個核心;

M1 Pro和Max有一個簇(E0)包含兩個E核心,兩個簇(P0和P1)分別包含4個P核心;

M1 Ultra有一個簇(E0)包含4個E核心,四個簇(P0、P1、P2、P3)分別包含4個P核心。

每個簇中的所有核心都執行在同一時鐘頻率下,而且通常(但並非所有情況下)會保持簇內的負載平衡。偶爾,負載分配會不均勻,某些極端情況下,一些執行緒可能會被分配到簇內的單一核心上。

執行緒控制

與Asashi Linux不同,macOS並不支援直接訪問核心、核心型別或簇,至少公開的API並沒有提供這些功能。通常,它們需要透過服務質量(QoS)設定中的Grand Central Dispatch來管理,macOS使用該功能來決定執行緒管理的策略。

最低QoS的執行緒只會在E簇上執行,而更高QoS的核心可以分配到E或P核心商。後者的行為可以透過taskpolicy命令列工具或setpriority()函式動態修改。這些工具可以限制高QoS執行緒只能在E和核心上執行,也可以在E或P核心上執行。但是,它們並不能改變最低QoS執行緒的規則,這些執行緒只能在E核心上執行。

macOS本身採用的策略是絕大部分後臺任務都以最低QoS執行。這些任務包括自動的時間機器備份、Spotlight索引維護等。歸檔工具(Archive Utility)的壓縮和解壓縮任務也在其中,例如,如果下載了xip格式的Xcode,解壓縮就會花費很長時間,因為程式碼只能在E核心上執行,而且沒辦法改變。

後臺執行緒

最低QoS執行緒在原始M1和M1 Pro/Max晶片上的載入和執行方式不同,因為兩者的E簇大小不一樣。

原始的M1晶片有4個E核心,因此QoS 9的執行緒執行時,時鐘頻率會設定為大約1000MHz(1GHz)。而只有兩個E核心的M1 Pro/Max採用了不同的做法:如果只有一個執行緒,則以1000MHz左右的頻率在簇上執行,但如果有兩個或更多執行緒,則頻率提高到2064MHz。這樣可以保證M1 Pro/Max的E簇能在簇大小不同的情況下,用差不多的功耗,提供至少相當於原始M1的後臺任務效能。

一個常見的例外是,某些擁有最低QoS的執行緒的程序(如backupd)還會受到I/O的制約,這樣的執行緒在M1 Pro/Max上會以1000MHz的頻率執行。

使用者執行緒

所有QoS高於9的執行緒的處理方式都差不多,但佇列的優先順序不同會導致不同的結果。

由於高QoS的執行緒可以在任意型別的簇上執行,因此M1和M1 Pro/Max的管理方式不一樣。原始的M1只有一個P簇,因此每次最多可以將8個執行緒分配到兩個簇上,每個簇執行4個執行緒。當執行緒數小於等於4個時,就會盡量全部分配到P簇上執行,只有當佇列中存在更多高QoS執行緒時才用到E簇。P核心的執行頻率大約為3GHz,而E核心為2GHz,大約是執行QoS 9執行緒時的頻率的兩倍。

M1 Pro和Max晶片一共有三個簇,其中兩個簇每個包含4個P核心,另一個簇包含兩個E核心。佇列裡的前4個執行緒會分配到第一個P簇(P0);如果存線上程5~8,就會分配到第二個P簇(P1),否則第二個P簇空閒,以降低功耗。如果佇列中還有更多執行緒,就會分配到E核心上。每種核心型別的最大頻率分別為:P0、P1為3228MHz,E0為2064MHz。

M1 Ultra晶片一共有五個簇,每個簇有四個核心。其策略和M1 Pro/Max晶片一樣,但會在所有四個P簇都被使用的情況下才會使用E0。

但是有兩種情況,程式碼看起來像是僅在一個核心上執行:在引導過程中,作業系統核心初始化並執行其他核心之前,程式碼只會在一個活躍的E核心上執行。另一種情況是在安裝macOS更新之前、“準備”下載更新的時候。在M1 Pro/Max晶片上,五個執行緒分配到相當於一個核心的資源,因此可以看到CPU使用率為100%,但被限制到一個P核心上,即第二個P簇(P0)中的第一個核心(下圖中的Core 3)。

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

這種不尋常的活躍核心分配情況在安裝更新之前的準備階段一直持續30分鐘左右。

高負荷的情況

下圖來自活動監視器的CPU歷史視窗,反映了更一般情況下macOS的策略效果。

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

上圖是原始M1晶片,逐漸增加大量佔用CPU的執行緒數目時的情況。它的兩個簇E0和P0由藍色的框標識。從左往右看,當只有高QoS的執行緒1~4時,負載完全被分配到P0簇上,然後執行緒5~8會佔用E0簇。

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

上圖是M1 Pro晶片在高負載下的情況,負載來自多個執行緒且不斷變化,一些執行緒是後臺QoS,一些是高QoS。大部分負載都分配到了E0簇的兩個核心中,P0也在大部分時間內處於滿狀態,而在高峰時期會用到P1。

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

上圖是M1 Ultra的情況,我按照簇重新排列了核心,頂端是E0,下面的兩列分別為P0~P3。圖中的負載是在登入之後幾分鐘內的典型負載,E0和P0上有大量負載,而前期負載較高時會分配到P1~P3上。

需要注意的一點是,活動監視器中並沒有提供有關M1核心的簇頻率的資訊。在小於1000MHz頻率下佔用100%CPU的簇(相當於活躍狀態)的核心上執行指令時,其速度只有以2064MHz頻率下佔用100%CPU的簇的一半。不幸的是,這個資訊只能透過命令列工具powermetrics獲得。

下圖給出了macOS對於原始的M1、M1 Pro和Max晶片的CPU核心的管理方式。

揭開 M1 晶片的秘密:macOS 如何管理核心分配?

蘋果將在六月初的WWDC上公佈M1系列的後續產品,我們很期待看到macOS管理M1晶片所用的核心架構和策略。

END