淺談GPU虛擬化技術(三)GPU SRIOV及vGPU調度

本系列文章推送門:

阿里雲鄭曉:淺談GPU虛擬化技術(第一章) GPU虛擬化發展史 
阿里雲鄭曉:淺談GPU虛擬化技術(第二章)GPU虛擬化方案之——GPU直通模式
今天一個小夥伴@我說:“你淺談一下,沒點技術背景的,估計都看不懂…”,醍醐灌頂啊,面向公衆的文章不是學術論文,應以普及基本概念爲主。所以我決定在接下來的文章力求寫的讓吃瓜羣衆能看懂,專業人士能讀完也會有很大感觸和啓迪。至於技術細節,大致就忽略不提了。

 

第三章 淺談GPU虛擬化技術(三)GPU SRIOV及vGPU調度

GPU SRIOV原理

談起GPU SRIOV那麼這個世界上就只有兩款產品:S7150和MI25。都出自AMD,當然AMD的產品規劃應該是早已安排到幾年以後了,未來將看到更多的GPU SRIOV產品的升級換代。S7150針對的是圖形渲染的客戶羣體,而MI25則針對機器學習,AI的用戶羣體。本文以圍繞S7150爲主。因爲S7150的SRIOV實例在各大公有云市場上都有售賣,而MI25目前看來尚未普及(受限於AMD ROCm生態環境的完備性)。

  • 兩個術語:SRIOV的PF,VF

(專業人士請自動忽略這部分介紹

PF:宿主機上的主設備,宿主機上的GPU驅動安裝在PF上。PF的驅動是管理者。它就是一個完備的設備驅動,與一般的GPU驅動的區別在於它管理了所有VF設備的生命和調度週期。比如下圖的07:00.0便是PF設備

VF:也是一個PCI設備,如下圖中的07:02.0和07:02.1。QEMU在啓動過程中通過VFIO模塊把VF 作爲PCI直通設備交由虛擬機,而虛擬機上的操作系統會安裝相應的驅動到這個直通的VF PCI 設備上(07:02.0)。VF設備佔用了部分GPU資源。比如下圖中一個PF上面劃分出了兩個VF,那麼很有可能跑在VF上面的虛擬機GPU圖形渲染性能宏觀上是PF的1/2。

上圖是一個帶有4個S7150的服務器,並且每個S7150 SRIOV虛擬出2個vGPU。

  • GPU SRIOV的本質

SRIOV的本質是把一個PCI卡資源(PF)拆分成多個小份(VF),這些VF依然是符合PCI規範的endpoint設備。由於VF都帶有自己的Bus/Slot/Function號,IOMMU/VTD在收到這些VF的DMA請求的過程中可以順利查找IOMMU2ndTranslation Table從而實現GPA到HPA的地址轉換。這一點與GVT-g和Nvidia的GRID vGPU有本質上的區別。GVT-g與Nvidia GRID vGPU並不依賴IOMMU。其分片虛擬化的方案是在宿主機端實現地址轉換和安全檢查。應該說安全性上SRIOV方法要優於GVT-g和GRID vGPU,因爲SRIOV多了一層IOMMU的地址訪問保護。SRIOV代價就是性能上大概有5%左右的損失(當然mdev分片虛擬化的MMIO trap的代價更大)。由於SRIOV的優越性和其安全性,不排除後續其他GPU廠商也會推出GPU SRIOV的方案。

  • 關於SRIOV 更多的思考

SRIOV也有其不利的地方比如在Scalable的方面沒有優勢。尤其是GPU SRIOV,我們看到的最多可以開啓到16個VM。設想如果有客戶想要幾百個VM,並都想要帶有GPU圖形處理能力(但是每個VM對圖形渲染的要求都很低),那麼SRIOV的方案就不適用了。如果有一種新的方案可以讓一個GPU的資源在更小的維度上細分那就完美了。事實上業界已經有這方面的考慮並付諸實踐了。

GPU SRIOV內部功能模塊

(吃瓜羣衆可以跳過)

由於沒有GPU SRIOV HW的spec與Data Sheet,我們僅能按照一般的常用的方式來猜測GPU SRIOV內部功能模塊(純屬虛構,如有雷同概不負責)。

 

GPU的資源管理涉及到vGPU基本上三塊內容是一定會有的:Display,安全檢查,資源調度。

  • Display管理

GPU PF需要管理分配給某個VF的FrameBuffer大小,以及管理Display相關的虛擬化。Display的虛擬化一般分爲Local Display和Remote Display。比如XenClient就是用的Display Local Virtualization,屬於本地虛擬化過程。此過程相當於把顯示器硬件單元完全交由當前虛擬機控制。在雲計算行業,Display更多的是採用Remote Display的方式。我們後續會講到行業中Remote Display的問題所在。

  • VF 安全檢查

GPU PF或者GPU SRIOV模塊需要承擔一部分的VF的地址審覈(Address Audit)和安全檢查,GPU SRIOV的硬件邏輯會保證暴露出的VF Register List並確保不包含特權Register信息,比如針對GPU微處理器和FW的Registers操作,針對電源管理部分的Registers也不會導出到VF中。而VM對所有VF的MMIO讀寫最終會映射到PF的MMIO地址空間上,並在PF的類似微處理器等地方實現VF設備的部分MMIO模擬。

另外一部分的安全檢查則是PF需要確保不同VF直接對GPU FrameBuffer的訪問隔離。這部分很有可能需要PF針對不同的VF建立GPU的Pagetable,或者Screen所有的VF提交的GPU BatchBuffer。

  • VF調度

AMD GPU SRIOV從硬件的角度看就是一個對GPU資源的分時複用的過程。因此其運行方式也是與GPU分片虛擬化類似。SRIOV的調度信息後續重點介紹。

GPU SRIOV的調度系統

  • 分時複用

VF的調度是GPU虛擬化中的重點,涉及到如何服務VM,和如何確保GPU資源的公平分片。 

 

GPU SRIOV也是一個分時複用的策略。GPU分時複用與CPU在進程間的分時複用是一樣的概念。一個簡單的調度就是把一個GPU的時間按照特定時間段分片,每個VM拿到特定的時間片。在這些時間片段中,這個VM享用GPU的硬件的全部資源。目前所有的GPU虛擬化方案都是採用了分時複用的方法。但不同的GPU虛擬化方案在時間片的切片中會採用不同的方法。有些方案會在一個GPU Context的當前BatchBuffer/CMDBuffer 執行結束之後啓動調度,並把GPU交由下一個時間片的所有者。而有些方案則會嚴格要求在特定時間片結束的時候切換,強行打斷當前GPU的執行,並交予下一個時間片的所有者。這種方式確保GPU資源被平均分攤到不同VM。AMD的GPU SRIOV採用的後一種方式。後續我們會看到如何在一個客戶機VM內部去窺探這些調度細節

 

  • 調度開銷

然而GPU的調度不同於CPU的地方是GPU上下文的切換會天然的慢很多。一個CPU Core的進程切換在硬件的配合下或許在幾個ns之內就完成了。而GPU則高達幾百ns(比如0.2ms-0.5ms)。這帶來的問題就是GPU調度不能類似CPU一樣可以頻繁的操作。舉一個例子:GPU按照1ms的時間片做調度,那麼其中每次調度0.5ms的時間花在了上下文的切換上,只有1ms的時間真正用於服務。GPU資源被極大浪費。客戶理論上也只能拿到66%的GPU資源。

 

  • S7150的調度細節

接下來我們來看一下作爲首款GPU SRIOV方案的S7150是如何調度的。由於S7150是中斷驅動的結構,所以通過查看虛擬機內部GPU中斷的分佈情況就可大致判斷出GPU SRIOV對這個虛擬機的調度策略。 

 

對於Windows的客戶機,我們可以在內部安裝Windows Performance kit,並檢測"GPU activity"的活動。

 

對於Linux的客戶機,則更簡單,直接查看GPU驅動的trace event。當然我們要感謝AMD在提供給Linux內核的SRIOV VF驅動上沒有去掉trace event。這讓我們有機會可以在VM內部查看到SRIOV的調度細節。(不知道這算不算一種偷窺?)

 

我們在阿里雲上隨便開啓一臺GA1的1/2實例。

並選擇Ubuntu(預裝AMD驅動)作爲系統鏡像;

在Console下查看所有的GPU相關的trace如下表:

 

 

很不錯,我們發現有兩個GPU驅動分發workload的event:amd_sched_job與amd_sched_process_job。

 

在VNC中開啓一個GPU Workload以後(比如Glxgears或者Glmark,當然我們需要先開啓x11vnc),我們通過下面Command來採集GPU數據。

trace-cmd record –e gpu_sched

… 等待幾秒中ctrl+c終止採集。

trace-cmd report > results.log

查看我們抓取這兩個event的事件並記錄下來幾個有趣的瞬間:

 

所有的log在一段時間內是連續的,然後斷開一段時間,然後又連續的workload提交。

 

截圖上的小紅框是我們需要關注的間隔時間。摘取如下表:

 

事件時間ns

間隔

 

1437.803888

1437.810159

6.271ms

無GPU活動

1437.816378

1437.822720

6.342ms

無GPU活動

1437.829105

1437.835127

6.022ms

無GPU活動

1437.841587

1437.847506

5.919ms

無GPU活動

很明顯在上述時間窗口期內當前VM的GPU被暫停了,並被切換至服務其他VM。因此當前VM的GPU workload會積壓在驅動層次。

 

我們把所有的event在圖表上打點後就可以發現,對於一個1/2GPU實例的VM來說,它佔用的GPU資源是基本上以6ms爲時間片單位做切換的。

作圖如下:

 

  • 估算vGPU的調度效率

我們假設每次vGPU的調度需要平均用到0.2ms,而調度的時間片段是6ms,而從上圖的結果來看,AMD GPU SRIOV是採用嚴格時間片調度策略。6ms一旦時間用完,則馬上切換至下一個VM(哪怕當前只有一個VM,也會被切走)。所以1/2實例的S7150的調度效率可以達到:96.7%如果有兩個這樣的VM同時滿負荷運行,加起來的圖形渲染能力可達到GPU直通虛擬化的96.7%以上。

 

實測結果如下:

1/2vGPU+ 1/2vGPU = 97.4% (vs GPU直通性能)

 

每一個vGPU可以達到直通GPU性能的48.x%,整體性能可以達到97.4%,與我們的預估非常接近。

 

更多的關於GPU虛擬化調度的思考

不得不說AMD S7150在vGPU調度上是非常成功的。AMD的GPU硬件設計保證了可以在任何當前GPU Batch Buffer的執行過程中可以被安全的搶佔(GPU Workload Preemption),並切換上下文到一個新的Workload。有了這樣卓越的硬件設計,才使得PF驅動在軟件層面的調度算法可以如此從容有序。6ms強制調度保證了多VM在共享GPU資源的情況下不會飢餓不會過度佔用。調度開銷極小(2-3%)。而且這樣的設計在VM數量不多的情況下可以進一步調整時間片的大小比如12ms,則GPU的利用率會更進一步提高。那麼爲什麼不能採用100ms調度呢?因爲Windows內核對"GPU activity"的活動有監視。任何GPU CMD在2秒內沒有響應,Windows就會發起Timeout Detected Recover(TDR),重置GPU驅動。設想如果你有16個VM,調度時間片爲100ms的情況下,平均一個VM輪轉到GPU資源的最小間隔就有1.6s。加上其他由於PF驅動被Linux內核調度的延遲,很有可能觸發Windows Guest內部的TDR。

 

不知不覺把GPU虛擬化的調度都在這章裏討論過了。很好,專門介紹GPU調度的章節可以省下來了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章