在一個多線程環境中,可能會有某些硬體資源在硬體拓撲的某一層,在物理上被共用。在多處理器系統中,一般,匯流排和儲存空間子系統在多個插槽之間在物理上被共用。在一個硬體多線程效能處理器內,某些資源為每個處理器核心而提供,而其它資源可以為每個邏輯處理器而提供(見8.7小節和8.8小節)。
從軟體編程角度,處理器操作的控制傳輸以邏輯處理器的粒度被管理(作業系統通過在平台上分配一個可用的邏輯處理器指派一個可啟動並執行任務)。為了管理在一個多線程環境中的共用資源的拓撲,理解並管理被多個邏輯處理器共用的資源對於軟體可能是有用的。
8.9.1 對共用資源的層級映射
在與一個多處理器系統中的每個邏輯處理器相關聯的APIC_ID是唯一的(見8.6小節)。這個8位或32位值可以被分解為子域,每個子域相應與硬體資源的拓撲映射的一個層級層。
一個APIC_ID的分解可以由幾個表示一個物理處理器包內的拓撲的子域構成,一個APIC ID的高次序位也可以被簇(Cluster)製造商使用,以表示每個相應的多處理器系統的簇結點的拓撲。如果處理器不支援CPUID分枝0BH,那麼8位初始的APIC ID可以表示4層層級:
1、簇(Cluster)——某些多線程環境由多處理器系統的多個簇構成。CLUSTER_ID子域往往被製造商韌體支援,以區別不同的簇。對於沒有簇的系統,CLUSTER_ID通常為0,並且拓撲被減少到3層層級。
2、包——一個多處理器系統由兩個或更多的插槽構成,每個插槽伴隨著一個物理處理器包。PACKAGE_ID區分在一個簇內的不同物理包。
3、核心——一個物理處理器包由一個或多個處理器核心構成。CORE_ID子域區分一個包中的處理器核心。對於一個單核心處理器而言,這個位域的寬度為0。
4、SMT——一個處理器核心提供了一個或多個共用執行資源的邏輯處理器。SMT_ID子域區分一個核心中的邏輯處理器。如果一個處理器核心提供了多於1個邏輯處理器的話,那麼此位域的寬度為非0。
SMT和CORE子域在APIC_ID域中是位寬連續的(見圖8-5)。
如果處理器支援CPUID分枝0BH,那麼32位APIC ID可以表示簇加上物理處理包內的若干拓撲層級。一個物理處理器包內的層級層的確切個數必須通過CPUID分枝0BH枚舉。通用的處理器家族可以引入類似8位初始APIC ID所表示的拓撲。一般來說,CPUID分枝0BH可以支援拓撲枚舉演算法,將一個32位APIC ID分解為大於四個子域(見圖8-6)。
每個子域的寬度依賴於硬體和軟體配置。域寬可以在運行時使用下面討論的演算法(例8-16到例8-20)確定。
圖7-6描述了在一個假想的MP系統中的三個層級子域之間的關係。
8.9.2 CPUID擴充拓撲分枝的層級映射
CPUID分枝0BH為軟體提供了枚舉參數以一個確定的形式識別處理器拓撲的每個層級。從SMT層開始的每個拓撲層級層用一個CPUID 0BH分枝內的子分枝索引,以數值方式表示出來。每個拓撲層被映射到APIC ID中的一個子域,遵從圖8-6中所描繪的通用關係。這個機制允許軟體直接查詢在一個物理處理器包內的確切的層級號,以及x2APIC ID的每個子域的位寬。比如:
1、從子分枝索引0開始,並遞增ECX直到CPUID.(EAX = 0BH,ECX = N):ECX[15:8]返回一個無效的“層次類型”編碼。在物理處理器包內的層次的個數為“N”(不包括PACKAGE)。用圖8-6作為一個例子,CPUID.(EAX = 0BH, ECX = 3):ECX[15:8]將報告00H,指示子分枝03H是無效的。這也可以用以下虛擬碼來描繪:
Byte type = 1;<br /> s = 0;<br /> while(type) {<br /> EAX = 0BH; // 查詢CPUID分枝0BH的每個子分枝<br /> ECX = s;<br /> CPUID;<br /> type = ECX[15:8]; // 檢查層次類型編碼<br /> s++;<br /> }<br />N = ECX[7:0];<br />
2、子分枝索引0(ECX = 0作為輸入)提供了枚舉參數,以萃取x2APIC ID的SMT子域。如果當執行CPUID時,EAX = 0BH並且ECX = 0被指定為作為輸入,那麼CPUID.(EAX=0BH, ECX=0):EAX[4:0]報告一個值(一個右移個數),允許軟體萃取x2APIC ID部分,以區分SMT層次上的下一個更高拓撲條目。這個值也對應於相應於帶有子分枝索引0的層級層次的x2APIC ID的子域的位寬。
3、對於每個後面更高的子分枝索引m,CPUID.(EAX=0BH, ECX=m):EAX[4:0]報告右移數量,這將允許軟體萃取x2APIC ID的部分以區分更高層次拓撲條目。這意味著在子分枝m的右移值m,對應於32位x2APIC ID的最低有效(m + 1)子域。
// 例8-17. x2APIC ID子域的位寬確定<br />for(m = 0; m < N; m++) {<br /> cumulative_width[m] = CPUID.(EAX=0BH, ECX= m): EAX[4:0];<br />}<br />BitWidth[0] = cumulative_width[0];<br />for(m = 1; m < N; m++) {<br /> BitWidth[m] = cumulative_width[m] - cumulative_width[m-1];<br />}<br />
當前,只有以下層級層次類型的編碼被定義:0(有效),1(SMT),2(核心)。軟體絕對不能假定任一“層次類型”編碼值被關聯到任一子分枝索引,除了子分枝索引0。
8.9.3 一個MP系統中的邏輯處理器的層級ID
對於Intel 64和IA-32處理器,系統硬體建立一個8位的初始APIC ID(或32位APIC ID,如果處理器支援CPUID分枝0BH),對每個邏輯處理器都是唯一的,跟在一次上電或RESET之後(見8.6.1小節)。系統上的每個邏輯處理器被分配一個初始的APIC ID。BIOS可以支援一些特徵,告訴OS支援少於系統匯流排上邏輯處理器的個數。在運行時,對應用程式停用那些邏輯處理器在OS引導過程期間被中止。這樣,可以通過親和化(affinitize)當前線程上下文而被查詢的有效本地APIC ID的個數,受限於在運行時被OS引導過程所允許的邏輯處理器的個數。