GPU虛擬機創建時間深度優化

從公有云服務商那裏購買過虛擬主機的資深用戶,一般會發現這麼個規律:創建一臺CPU虛擬主機是比較快的,但是要創建一臺包含GPU卡的虛擬主機通常需要等比較長的時間,整個創建過程短則數十秒鐘,長則數分鐘。對於絕大多少的用戶來說,虛擬主機的創建時間長一點對他們影響並不大,因爲創建虛擬機屬於相對低頻操作。但是也會有一些特定的用戶由於其業務場景交互性比較強,會對虛擬主機的創建時間有相對苛刻的要求,因爲過長的創建時間會導致其業務用戶體驗很差。本文將從虛擬化的角度來介紹GPU虛擬主機創建時間長背後的原因,以及相關的優化方法。

通過分析Libvirt, QEMU以及Guest 內的相關日誌及對應的時間戳,可以獲取GPU虛擬主機在創建過程中的耗時情況,這裏我們主要關心幾個關鍵的時間點: a) Libvirt 開始創建QEMU 進程;b) Libvirt 執行 Resume啓動VCPU ; c) Guest kernel 打印第一條日誌. 在本文中,我們把a和 b 之間的時間間隔稱爲QEMU初始化時間, 把b 和c 之間的時間間隔稱爲 BIOS執行時間。以下數據是在滴滴雲的線上環境中採集到的創建一臺包含8個CPU核虛擬機實例的相關數據:

從上面的數據可以看到,對於規格相同的虛擬機實例,帶1塊P40卡的GPU實例相比同規格的CPU實例在QEMU初始化及BIOS執行部分的時間都明顯要長, 在帶4塊P40卡以及更大內存規格的場景下,需要的時間會進一步拉長。通過實驗我們發現在主機配置和GPU卡型號確定的前提下,GPU實例的創建時間長短主要取決於兩個因素:虛擬機的內存大小和GPU卡的數量。

爲什麼GPU實例的創建過程要比CPU實例的創建過程耗時長?多消耗的時間到底花在哪裏?要搞清楚原因需要深入的分析,比較直觀的辦法就是通過perf採樣來生成火焰圖,以此來分析虛擬機在創建過程中的熱點函數。下圖是在滴滴雲環境裏抓取到的GPU虛擬機啓動過程中QEMU進程的火焰圖。

通過對代碼調用關係的分析,可以得知熱點發生在系統分配內存和對內存頁面清零的過程中,是由QEMU中的vfio_dma_map函數在執行VFIO_IOMMU_MAP_DMA ioctl 系統調用所觸發,該調用會Pin住所有分配給VM當做RAM使用的內存。在Pin 內存的過程中,如果虛擬內存對應的物理頁面尚未分配,會先進行物理內存分配並對內存頁面內容進行清零。在Linux kernel 中,對分配給應用程序的內存進行清零主要是基於安全方面的考慮,避免Host 內存中的內容泄漏給用戶空間的應用程序。這裏之所以要將內存Pin 住,目的是爲了保證IOMMU IO頁表和 host HVA->HPA 映射的一致性,否則Guest 內設備的DMA操作可能會訪問到錯誤的內存頁面。

VFIO DMA 映射處理慢可以在一定程度上解釋爲什麼內存的大小和GPU卡的數量會影響到GPU實例的創建時間。虛擬機實例內存規格越大,需要映射和Pin住的內存量也就越大,相關處理的耗時和內存量成正比。另外GPU卡上通常會包含一塊比較大的MMIO區域,對MMIO的映射也會耗費較多的時間,卡的數量越多,耗時就會越長。相比之下,CPU實例的創建過程沒有VFIO DMA 映射的相關處理流程,因此會比較快。

針對以上的熱點,有什麼辦法可以消除或者緩解呢?已經有業內的同行們提到過這個問題並給出了對應的解決方案,其思路是對分配給VM 用作RAM使用的內存區域做一個標記,在內核中跳過對標記的內存頁面進行清零,而將清零的動作留給QEMU來做,在QEMU 中可以利用多線程以及更高效的指令進行清零動作,從而加速Pin內存的過程。該方案的缺陷主要有兩點: 一是存在安全性風險,其他應用程序可以利用設定的標記來窺探host 內存中的信息;二是在VM實例的VCPU個數比較少的情況下,優化效果不是很好。

我們採用了另外一種方案,通過修改Host kernel的內存管理部分, 我們實現了一種對Host 上空閒物理內存提前進行清零的機制,清零動作可以在系統空閒的時候進行,當某個內存頁面被清零後,將其對應的 struct page 進行標記,這樣在需要對內存進行清零的時候,可以通過檢查該標記來判斷是否要執行清零動作,如果清零的標記已經被設置,就可以跳過清零的步驟。該方案避免了上述方案中的兩個主要問題,同時還有其它方面的好處,主要包括以下幾點:a.可以提高缺頁異常處理效率,尤其是透明大頁的缺頁異常處理效率;b. 可以加速需要Pin內存及需要通過mlock 來鎖住內存的應用場景,例如使用RDMA, QAT 硬件加速等場合;c. 可以加速內核中其他需要對內存進行清零的場景。相關補丁的RFC版本,我們已經提交到了Linux kernel 社區。

另一個加速Pin內存的有效方法是採用大頁,通過開啓透明大頁可以顯著減少缺頁處理的調用次數並加速Pin內存的過程。下圖展示了開啓透明大頁以及啓用空閒內存預清零機制對GPU實例創創建時間的影響。

以上的數據表明,在開啓透明大頁以及空閒內存預清零功能後,可以顯著的的優化QEMU的初始化時間,但是BIOS部分的耗時依然偏長。通過進一步的分析我們發現主要的時間消耗還是在VFIO 映射DMA的處理過程當中,主要有幾個方面的原因:a. 映射DMA Pin內存需要逐頁查詢頁表,開銷較大;b. QEMU 存在對部分IOVA區域的反覆映射及解除映射的操作。於是我們嘗試在這兩個方向上進行優化,通過採用批量處理的方法減少查詢頁表的開銷,另外在QEMU中加入VFIO DMA映射區域的管理,有效的規避了效率低下的反覆映射及解除映射操作,最終大幅度降低了VFIO DMA映射的時間消耗。

在解決完上述問題後我們並沒有止步,對虛擬機實例創建過程中的可優化的其它地方,我們也做了相關的處理,例如關閉BIOS boot menu ,優化VFIO PCI 設備reset 的流程,去掉對GPU實例來說不必要的操作,最終將GPU實例創建過程中虛擬化部分的時間開銷減少了90%以上,下面這張圖展示了單卡小內存規格實例優化前後的耗時對比:

大內存規格和多GPU卡的效果更加顯著,時間減少了95%以上,相關數據如下圖:

經過上述的優化,目前在滴滴雲上創建一個GPU實例的速度比優化前顯著加快,甚至比優化前創建一個CPU實例的速度還要快,如果用戶對GPU實例的創建速度有比較強的需求,歡迎到滴滴雲上進行體驗。 除此之外,滴滴雲GPU產品現已開通企業0元體驗,請在滴滴技術公衆號後臺回覆「GPU」立即獲取。

作者介紹

李亮,滴滴高級專家工程師

專注於系統虛擬化研究,負責解決滴滴雲底層虛擬化相關技術問題。曾就職於Intel 開源軟件中心虛擬化組,具備豐富的底層系統軟件開發經驗。

本文轉載自公衆號滴滴技術(ID:didi_tech)。

原文鏈接

GPU虛擬機創建時間深度優化

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