簡體   English   中英

多核調度

[英]Scheduling on multiple cores

多處理器調度與單處理器調度

一般來說,多核 CPU 系統存在一個巨大的問題——緩存一致性。

緩存一致性是什么意思?

很難訪問主 memory。 根據 memory 的頻率,訪問 RAM 中的一些數據可能需要幾千到幾百萬個周期 - 這是 CPU 沒有做任何有用工作的大量時間。 如果我們盡可能地減少這個時間會好很多,但是這樣做所需的硬件很昂貴,並且通常必須非常靠近 CPU 本身(我們說的是在內核的幾毫米范圍內) )。

這就是高速緩存的用武之地。高速緩存將一小部分主要 memory 保留在靠近內核的位置,從而允許訪問此 memory 比主要 ZCD69B4957F06CD818D7BF3D61980E29 快幾個數量級讀取這是一個簡單的過程 - 如果 memory 在緩存中,則從緩存中讀取,否則從主 memory 讀取。

寫作有點棘手。 寫入緩存很快,但現在主 memory 仍然保持原始值。 我們可以更新 memory,但這需要一段時間,有時甚至比讀取時間更長,具體取決於 memory 類型和電路板布局。 我們如何也盡量減少這種情況?

最常見的方法是使用回寫緩存,當寫入緩存時,將在稍后 CPU 空閑或不做某事時將緩存中包含的數據刷新回主 memory。 根據 CPU 架構,這可以在空閑條件下完成,或者與 CPU 指令交錯,或者在計時器上完成(這取決於 CPU 的設計者/制造者)。

為什么這是個問題?

在單核系統中,讀寫只有一條路徑——它們必須通過高速緩存 go 到達主 memory,這意味着在 CPU 上運行的程序只能看到它們所期望的——如果它們讀取一個值,修改它,然后讀回來,它會被改變。

然而,在多核系統中,當返回主 memory 時,數據有多個路徑可供選擇,具體取決於發出讀取或寫入的 CPU。 這帶來了回寫緩存的問題,因為“稍后”會引入一個間隙,其中一個 CPU 可能會讀取尚未更新的 memory。

想象一個雙核系統。 作業在 CPU 0 上啟動並讀取 memory 塊。 由於 memory 塊不在 CPU 0 的緩存中,它是從主 memory 讀取的。 稍后,作業寫入該 memory。 由於高速緩存是回寫式的,因此該寫入將寫入 CPU 0 的高速緩存並稍后刷新回主 memory。 如果 CPU 1 然后嘗試讀取相同的 memory,CPU 1 將嘗試再次從主 memory 讀取,因為它不在 CPU 1 的緩存中。但是來自 CPU 0 的修改還沒有離開 CPU 0 的緩存,所以您取回的數據無效 - 您的修改尚未完成。 您的程序現在可能會以微妙、不可預測且可能具有破壞性的方式中斷。

因此,緩存同步是為了緩解這種情況。 存在應用程序 ID、地址監控和其他硬件機制來同步多個 CPU 之間的緩存。 所有這些方法都有一個共同的問題——它們都迫使 CPU 花費時間進行簿記,而不是實際的、有用的計算。

避免這種情況的最佳方法實際上是盡可能將進程保留在一個處理器上。 如果進程沒有在 CPU 之間遷移,則不需要保持緩存同步,因為其他 CPU 不會同時訪問 memory(除非 memory 在多個進程之間共享,但我們將不是 go 到這里)。

現在我們來討論如何設計我們的調度程序,以及其中的三個主要問題——避免進程遷移、最大化 CPU 利用率和可伸縮性。

單隊列多處理器調度 (SQMS)

單隊列多處理器調度程序是您建議的 - 一個包含可用進程的隊列,每個核心訪問該隊列以運行下一個作業。 這實現起來相當簡單,但有幾個主要缺點 - 它可能導致大量進程遷移,並且不能很好地擴展到具有更多內核的大型系統。

想象一個有四個核心和五個作業的系統,每一個都需要大約相同的時間來運行,並且每一個在完成時都會重新調度。 在第一次運行時,CPU 0 占用作業 A,CPU 1 占用 B,CPU 2 占用 C,CPU 3 占用 D,而 E 留在隊列中。 然后假設 CPU 0 完成作業 A,將其放在共享隊列的后面,並尋找另一個作業來完成。 E 當前在隊列的前面,CPU 0 占用 E,然后繼續。 現在,CPU 1 完成作業 B,將 B 放在隊列的后面,並尋找下一個作業。 它現在看到 A,並開始運行 A。但由於 A 之前在 CPU 0 上,CPU 1 現在需要將其緩存與 CPU 0 同步,導致 CPU 0 和 CPU 1 都失去了時間。此外,如果兩個 CPU 都同時完成他們的操作,他們都需要寫入共享列表,這必須按順序完成,否則列表將被破壞(就像在多線程中一樣)。 這需要兩個 CPU 中的一個等待另一個完成寫入,並將其緩存同步回主 memory,因為列表在共享 memory 中,添加的 CPU 越多,此問題就會越來越嚴重,從而導致重大問題大型服務器(可能有 16 個甚至 32 個 CPU 內核)。 並且在超級計算機上完全無法使用(其中一些具有超過 1000 個內核)。

多隊列多處理器調度 (MQMS)

多隊列多處理器調度程序的每個 CPU 內核有一個隊列,確保可以完成所有本地內核調度,而無需獲取共享鎖或同步緩存。 這允許具有數百個內核的系統在每個調度間隔運行而不會相互干擾,這可能每秒發生數百次。

MQMS 的主要問題來自CPU 利用率,其中一個或多個 CPU 內核正在完成大部分工作,以及調度公平性,其中計算機上的一個進程比具有相同優先級的任何其他進程更頻繁地被調度。

CPU 利用率是最大的問題 - 如果安排了作業,則任何 CPU 都不應該處於空閑狀態。 但是,如果所有 CPU 都忙,所以我們將一個作業調度到一個隨機的 CPU,而另一個 CPU 最終變得空閑,它應該從原始 CPU 中“竊取”調度的作業,以確保每個 CPU 都在做真正的工作。 但是,這樣做需要我們鎖定兩個 CPU 內核並可能同步緩存,這可能會降低我們通過竊取計划作業獲得的任何加速。

綜上所述

這兩種方法都存在——Linux 實際上有三種不同的主流調度器算法,其中一種是 SQMS。 調度器的選擇實際上取決於調度器的實現方式、您計划運行它的硬件以及您打算運行的作業類型。 如果您知道您只有兩個或四個內核來運行作業,那么 SQMS 可能就足夠了。 如果您運行的超級計算機的開銷是一個主要問題,那么 MQMS 可能是通往 go 的方式。 對於桌面用戶——只要相信發行版,無論是 Linux OS、Mac 還是 Windows。 一般來說,你所擁有的操作系統的程序員已經完成了他們的功課,確切地說什么調度程序將是他們系統典型用例的最佳選擇。

本白皮書描述了兩種類型的調度算法之間的差異。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM