Categories
程式開發

異構計算系列文章(一):定義、場景及局限性


誕生伊始,計算機處理能力就處於高速發展中。及至最近十年,隨著大數據、區塊鏈、AI 等新技術的持續火爆,人們為提升計算處理速度更是發展了多種不同的技術思路。大數據受惠於分佈式集群技術,區塊鏈帶來了專用處理器(Application-Specific IC, ASIC)的春天,AI 則讓大眾聽到了“異構計算”這個計算機界的學術名詞。

異構計算系列文章(一):定義、場景及局限性 1

“異構計算”(Heterogeneous computing),是指在系統中使用不同體系結構的處理器的聯合計算方式。在 AI 領域,常見的處理器包括:CPU(X86,Arm,RISC-V 等),GPU,FPGA 和 ASIC。 (按照通用性從高到低排序)

AI 是一門較為複雜、綜合的學科。在只有 CPU 平台的情況下,AI 開發者要學習的算法、模型、框架、編程語言已經不少。如果再考慮多個不同處理器平台,情況會變得更為複雜。在展開討論不同的應用場景之前,我們先了解一下什麼是“異構計算”。

異構計算

首先需要明確的是,計算機體系結構≠硬件架構。體系結構不單包括硬件層面的實現,也包括軟件層面的考量。當IBM在S/360服務器中提出體系結構這個概念之前,每一代IBM服務器的硬件實現都會有所不同(其實今日的處理器硬件亦是如此)。由此帶來了各不相同的指令,以至於開發者編寫的軟件無法在不同的IBM服務器上運行。

因此,經典的體系結構概念與軟硬件的界面——指令集有比較大的關係。通常來講,如果兩個處理器都能支持同一套指令集,那麼可以認為它們有相同的體系結構。好比AMD的CPU和Intel的CPU都屬於X86 CPU。

雖然異構計算能帶來潛在的算力提升,但也會造成額外的開發成本。在進行異構計算開發之前,開發者需要進行幾個方面的評估。

第一,權衡代碼通用性與代碼性能。

今天的 AI 開發者恐怕只在較少的情況下可能會直接使用指令集進行編程(例如,X86 CPU 的 AVX2 指令等),絕大多數情況下,我們用到的主要是些程序庫。然而程序庫在不同平台上的實現依舊需要調用底層的指令集。在 AI 這樣需要高性能編程的領域,常用的 BLAS (Basic Linear Algebra Subprograms)程序庫就有多種選擇:

部分常用的 BLAS 庫 支持的平台
OpenBLAS X86,Arm
Intel MKL Intel X86 CPU
Arm Performance Lib Armv8-A
cuBLAS Nvidia GPU

即便只使用 CPU 進行計算,依然會面臨諸如 OpenBLAS 和 Intel MKL 之間的選擇。開發者需要根據具體需求謹慎評估通用性與性能之間的優先級。 AI 這些年雖然很火,但是 AI 應用收益與開發成本的矛盾也一直較為突出。

第二,考慮開發環境的成熟度。

雖然 AI 開發者可用的計算硬件有 CPU,GPU,FPGA,ASIC 等,目前開發環境比較成熟的是 CPU,GPU 和 FPGA。 ASIC 在開發成熟度上目前較為尷尬,因為應用專有芯片的開發依賴於所瞄準的應用是否已經達到了一個比較成熟的階段。而 AI 領域中,即便是最成熟的機器視覺(CV)也依然還在持續發展中。因此,ASIC 廠商要打造一個較為穩定的開發環境面臨一定的挑戰。

這也無怪乎年初知名的“礦業”公司爆出了 AI 芯片團隊大規模裁員的消息。

第三,考慮技術普及程度。

越普及的技術硬件成本越低,人才儲備也更為充足。這一點上, FPGA 就比較佔劣勢,畢竟一般人很少機會接觸 FPGA 硬件。

因此,目前異構計算開發仍然以 CPU 結合 GPU 為主。

尋找異構計算場景

要真正發揮異構計算的優勢,必須得尋找合適的場景。否則 GPU 等協處理器並不總是能帶來性能的提升。我們先來回想一下 GPU 最典型、最擅長的應用場景——大型3D遊戲是怎麼樣的:

  1. 把遊戲數據載入顯存
  2. 在用戶遊戲的過程中,顯卡始終在進行高速運算

以上看起來好像是一段廢話,但要理解 GPU 等協處理器的特點,這段廢話值得反復回味。 GPU 的優勢場景在於:

  1. 一定量的數據。如果數據量太小,那麼 GPU 可能會比 CPU 慢。如何判斷這個臨界點也很簡單,可以利用 Python 的 Pandas dataframe 和 RAPIDS 的 cuDF 進行一個對比測試。

  2. 數據量不能太大,顯存一定要裝得下。一旦發生顯存對外的 I/O(哪怕是內存和顯存之間的),處理速度依然會受到很大影響。

  3. 需要有持續的工作流發送給 GPU 處理。計算核心更多的 GPU 啟動代價比 CPU 高得多。

看似矛盾的第一點和第二點說明,要找到異構計算的優勢場景並不容易。事實上,一個計算任務的處理時間包括計算與 I/O(CPU 訪問內存也算在內)兩部分。高算力的 AI 處理器可以幫你加速計算的部分,但礙於服務器架構,異構計算也會帶來一些額外的 I/O 開銷。因此,問題的關鍵在於一個程序的處理時間究竟是花在計算上更多,還是花在 I/O 上更多。

在 Linux 系統下,我們可以通過 perf 工具(Linux kernel profiling)來了解一個處理任務執行時的 CPU 計算繁忙程度。

異構計算系列文章(一):定義、場景及局限性 2

(引用自: https://perf.wiki.kernel.org/index.php/Tutorial

在上面的示例中,IPC(Instructions Per Second)僅為 0.679,要知道現代的 CPU 單核 IPC 理論峰值可以達到 10。一般認為,運行時 IPC 如果低於 1,說明正在運行的工作流在 I/O(CPU 讀取內存)上花的時間更多。在這種情況下,異構計算帶來的提升就不太可能像硬件廠商宣傳的那樣達到10倍,甚至100 倍。

前面提到“異構計算也會帶來一些額外的 I/O 開銷”。這主要受限於以 CPU 為核心的系統架構,其他協處理器只能通過 PCI/E 連接到系統。當需要把數據從硬盤載入到顯存的時候:(假設使用 PCI/E 硬盤)

  1. 數據從硬槃經過 PCI/E 複製到內存
  2. 數據從內存經過 PCI/E 複製到顯存

在這種情況下,數據從硬盤載入顯存的速度只有 PCI/E 傳輸速度的一半。為了解決這個問題,GPU 廠商開發了 GPUDirect Storage 技術,這樣可以直接把數據從硬盤加載到顯存。

異構計算系列文章(一):定義、場景及局限性 3

(引用自: https://devblogs.nvidia.com/gpudirect-storage/

一般企業級計算顯卡的顯存大小為 16GB 或 32GB,而一般企業級 CPU 的內存上限可以達到 768GB 或 1TB。在海量數據的場景下,如何利用異構算力需要仔細的設計,不然異構計算產生的 I/O 開銷可能會適得其反。

異構計算在 AI 中的應用

異構計算的優勢與局限都非常突出。在 AI 的全流程中,開發者逐漸在以下階段中找到了異構計算的場景。

  • 數據準備階段

不同於傳統大數據應用,AI 應用的數據不但包括一般的結構化數據,也包含了大量非結構化數據(如圖片、視頻、聲音、文本等)。針對海量結構化數據的處理,因為通常 I/O 佔比遠高於計算佔比,因此這部分數據的處理依舊以 CPU 為主。不過,今天的 CPU 也提供了 AVX2 向量指令集進行 SIMD 計算(單指令多數據)。

但在非結構數據,尤其是圖片、視頻等的轉解碼處理上,異構芯片的優勢還是比較明顯。

  • 模型訓練、調優階段

目前的深度學習模型主要是基於張量(tensor based)模型,很多 AI 處理器會著重加強自己的乘累加(MACC,基礎的矩陣計算操作)處理能力。模型訓練是整個 AI 流程中異構計算最為有優勢的部分。 GPU,TPU 和其他一些 ASIC 都能在這裡發揮作用。

回想一下前文中討論過的遊戲場景,模型訓練是不是和它很像呢?

  • 運行時階段

運行時的任務主要包括模型推理,向量相似度搜索等。

模型推理本身並不需要像模型訓練那樣進行大規模計算,但模型推理往往涉及多種不同類型的硬件部署平台。因此,模型推理中的異構計算首要任務不是融合算力,而是考慮代碼的跨平台通用性以降低開發成本。業界已經有一些開源模型推理框架來解決代碼的跨平台通用性問題,比如 Linux 基金會旗下的 Adlik 和 微軟的 ONNX RT。

向量相似度搜索,是圖片、視頻搜索、推薦系統、問答系統中的常用技術。由於要搜索的特徵向量規模往往會達到上億甚至十億級,搜索時的 I/O 比重很高,異構計算在搜索時的幫助會比較有限。但是在建立向量相似度索引時卻是一個典型的計算密集型任務,異構計算能大幅提升索引創建速度。供開發者參考的開源項目有 Facebook Faiss、Spotify Annoy、NMSLIB以及 Linux 基金會旗下的 Milvus 等。

總結

作為異構計算專題的開篇,本文整體性的介紹了異構計算的定義,場景與局限性。在後續的專題文章中,我們將深入不同的 AI 應用場景進一步解釋異構計算的優勢。

作者簡介:

顧鈞,畢業於北京大學,在數據庫相關領域有 15 年經驗。目前任職於 ZILLIZ,負責 Milvus 開源向量搜索引擎的社區建設與推廣。