一窩瘋「人工智慧晶片」前,你需要知道的幾件關於 GPGPU 的事

作者 | 發布日期 2017 年 09 月 12 日 13:39 | 分類 GPU , 晶片 , 科技教育 follow us in feedly

聽說拜「人工智慧」與「深度學習」之所賜,GPU 應用看起來很夯,大家搶著挖礦讓顯示卡一片難求,搞得最近 nVidia 和 AMD 的股價漲得很兇。



喔齁。

隨著 1999 年 8 月 31 日發表的 GeForce 256(NV10),nVidia 創造了「GPU」(Graphic Processing Unit)這個看起來好像非常偉大的名詞,其近 20 年演進,顛覆了眾人對「處理器」一詞的傳統認知,也衍生琳瑯滿目、雞同鴨講、讓人摸不著頭緒、需勞駕計算機結構大師的教科書,長篇大論釐清命案現場的「技術行銷名詞」,而追求繪圖處理器泛用化的 GPGPU,在 nVidia 的推波助瀾下,更激發了無數人對未來的期望、憧憬、與幻想,甚至是令人匪夷所思的誤解、謬誤,與浮誇。

部分讀者可能並未經歷過顯示晶片市場,從百家爭鳴,一路彷彿 x86 處理器的市場發展,走上 nVidia 與後來被 AMD 併購的 ATI,雙雄相爭的過往,特此野人獻曝,寄望可遞上一塊讓你挺立於沒頂時代洪流中的踏腳石,也希望可以順便喚回老骨頭讀者學生時代的珍貴回憶。

有鑑於在這資訊大爆炸的網路時代的普遍現象:毋需倡議提高國文教材的文言文比重,也不必端起出師表臨卷涕泣,一篇白話文只要字數超過 500,就會經常性誘發基礎閱讀能力不佳的大腦 buffer overflow,只看標題引文關鍵字自動腦補後,就開始留言發表原作者根本不知所云完全一頭霧水的高見,所以本文從頭到尾一問一答,不留下任何一絲一毫「誤讀」的可能性,也盡量避開因 GPU 廠商行銷需求,大量孳生的專有「技術行銷名詞」與縮寫,更忌諱「用名詞解釋名詞」,減少閱讀時「卡彈」的機率。

本文章節依序如下:

  • 什麼是 GPU?
  • 學理角度的 GPU是什麼?
  • GPU 為何多執行緒?
  • SIMD 的三種常見型態?GPU 何以承先啟後?
  • 為何 GPU 是多執行緒 SIMD?
  • GPU 雙雄又是如何定義 GPU 的運算型態?
  • 什麼是 GPGPU?
  • GPU 雙雄的產品演進?
  • 為何要先不傷現在,再講求未來?
  • 從 HPC 到工人智慧……人工智慧。
  • 回首 20 年來時路。

近年來英明神武天下無敵的 GPU,到底是什麼?

根據不學無術的筆者腦內考證,nVidia 對 GPU 一詞的最初技術定義是「整合的 3D 轉換(Transform)、打光(Lighting)、三角設定(Triangle Setup)/裁切(Clipping)與成像引擎(Rendering Engine),每秒能處理至少 1 千萬個多邊形的單晶片處理器」。

我們很清楚,這「定義」已毫無任何意義。

說穿了,這只是蓄意突顯當時只有 nVidia 率先支援 DirectX 7.0 硬體 Transform & Lighting(Hardware T&L)的行銷手法,刻意集中打擊產品發展與公司營運已陷入困境的衰退霸權 3dfx。

筆者還依稀記得,3dfx 曾經花了很大工夫在網站首頁用酷炫的 Flash 拚命宣傳「Banshee 2」(Voodoo 3 的暱稱,根本只是補回第二個 TMU 的 Banshee)與 VSA-100 疊疊樂的 Voodoo 4/5 系列,其 1,600×1,200 60fps 和反鋸齒的實用性。

3dfx 在 2000 年破產後,即被 nVidia 併購,其末代產品「Rampage」核心設計團隊,後來接手操刀由 IBM 代工製造、nVidia GPU 歷史不朽名作 GeForce 6(NV40)系列,拯救了深陷 NV30 災難的 nVidia。

總而言之,現在只要是繪圖晶片,GPU 幾乎等同於代名詞,連過去無緣躬逢其盛的 2D 前輩,也同樣雞犬升天,被「追封」這個在今日已失去意義的空頭銜,而某些僅需提供 2D 畫面輸出、隱身於某些特殊應用,如伺服器 IPMI BMC 的繪圖核心(提醒你,Matrox G200 還活得好好的喔),就不在本文的雷達搜索半徑之內。

以學理的角度來看,GPU 的本質到底是什麼?

GPU 本質上多樣化的平行性,涵蓋了指令階層、多執行緒、SIMD(單指令多資料流)、與以多處理器環境的 MIMD(多指令多資料流),那我們該以哪個角度來理解 GPU?

直接在這裡講結論:GPU 是「由數個多執行緒架構的 SIMD 處理器(如 nVidia 的 SM / SMX / SMM,AMD 的 SIMD Engine / CU),所組成的 MIMD 多處理器環境」,硬體層級可簡述如下:

GPU 的靈魂在於「被執行緒區塊排程器(Thread Block Scheduler)指派給執行該程式碼的多執行緒 SIMD 處理器(Multi-thread SIMD Processor),對 GPU 以巨大的暫存器檔案,掩蓋記憶體延遲」,那層看起來很像 MIMD 的外皮,完全不是重點,請對 GPU 的認知,聚焦在 SIMD 和多執行緒上。

為何 GPU 的多執行緒像紡紗機般地千絲萬縷?

答案很簡單:需要同時執行滔滔不絕的多執行緒隱藏記憶體延遲。

CPU 通常使用快取記憶體來減少存取主記憶體的次數,防止記憶體延遲拖慢指令管線執行效率,但 GPU 因平行處理與存取材質,繪圖系統的記憶體往往「高頻寬,高延遲」,需多執行緒「交替掩護」,隱藏記憶體存取延遲,如第一個執行緒等待記憶體存取結果時,開始執行第二個執行緒,維持執行單元滿載。

不像 CPU 藉由分支預測減少管線停滯,GPU 多半使用類似上述處理記憶體延遲的方式,減輕分支指令造成的效能損傷,但一般而言,通常 GPU 處理分支指令的效能比 CPU 來得差。

相異於泛用 CPU 的指令執行流程,繪圖管線並非「一條腸子通到底」,橫跨數個運算特性相異的功能階段,要穩定執行效能,需更有效精確掌握所有功能單元的執行狀態與資源分配。

簡而言之,「以硬體為基礎的多重執行緒管理與排程」是近代 GPU 的最重要技術核心,當同時數幾百條、個別代表一個像素(Pixel)的執行緒,去繪製同一張畫面,每個 SIMD 執行緒區塊、等同一個 8-32 像素的處理時,光要有效同步化,避免少數執行緒拖垮整體效能,就是非常不簡單的挑戰,而充分將 GPU 的巨大運算潛力發揮到極限,更是舉足輕重。

SIMD 三種常見形式(向量運算、SIMD 擴充指令集、GPGPU)的異同?

因單指令多資料(SIMD)可單指令啟動多筆資料運算,比起每道資料運算都需要執行一道指令的多指令多資料(MIMD)享有更多潛在的能量效率。

另外,就程式設計師的角度,SIMD 對上 MIMD的最大優點,不外乎可以延續既有的循序性思考,卻可利用資料階層的平行化運算提昇效能。在設法理解 GPU 的本質和優點前,絕不可忽略這點。

時下常見的 SIMD 有三種:

  1. 歷史悠久的向量架構電腦,像 1976 年的 Cray-1 超級電腦與後代子孫,和今天依然很有名的 NEC SX 系列向量處理器(沒研究過超級電腦,總得聽過日本橫濱那台 Earth Simulator 吧)。
  2. 近 20 年來蓬勃發展的多媒體 SIMD 指令集延伸,想必各位對 PowerPC 的 AltiVec 及 x86 指令集一路從 MMX、3D Now!、SSE、SSE2、SSE3、SSE4(別忘了還有還沒開始就結束的 SSE5,但這是 AMD 打算推的)、AVX、AVX2 到 AVX-512 的演進一點不陌生。
  3. 近十年來從起步跌跌撞撞,到今日看似有模有樣的 GPGPU。

這三種架構看起來很像,但本質上有太多根本性的差異,先簡單解釋 SIMD 最簡潔美觀的向量電腦,再以其為基準點,去檢視這三者的異同,更能體驗 GPU 微架構暗藏的「撇步」,這是廠商的行銷簡報不會告訴你的奧祕。

向量(Vector)運算是一種簡單到有時候還真的不知道該如何好好闡述的平行計算方式。在科學計算中,有大量彼此不相關的資料進行同一種運算,正好便於單一指令,對不同的資料,執行相同的重複操作。

向量電腦擷取以不同「跨度」(Stride)散布於記憶體各處的資料元素,「聚集」(Gather)於大型的循序式暫存器檔案,存取非循序的記憶體位置,並將全部元素重塑為緊密結構,在這些暫存器中進行資料運算,再將運算結構「分散」(Scatter)回記憶體中,像多維陣列和稀疏矩陣,就是能夠充分發揮向量電腦威力的場合。

為了說明向量處理的基本概念,下面舉一個迴圈操作範例,將陣列 B 內的 16 個元素個別加上 1,再將結果存入陣列 A:

I = 1,16

A (I) = B (I + 2) + 1

其中常數 1 和陣列 A / B 中的每個元素是「純量」(Scalar),通常一條純量指令只能處理一個或一對運算元,處理 n 個或 n 對運算元,至少就需要 n 個指令。

在一般的電腦上,就會變成這樣的程式迴圈:

I = 1

取出B (I + 2)

計算B (I + 2) + 1

存入 A (I) = B (I + 2) + 1

I = I + 1

連續跑 15 次,直到 I=16 為止。不僅曠日費時,且可能因處理器的分支預測錯誤,而拖累管線效能(在這範例,理論上會發生一次)。

但導入向量運算「整排處理」,事情就簡單了:

取出 B (I + 2)

計算 B (I + 2) + 1

存入 A (I) = B (I + 2) + 1

第一個指令取出陣列 B 的 16 個元素,第二個指令對陣列 B 的每個元素分別加上 1,第三個指令則將結果存入陣列 A。三個指令即可搞定,更不會製造分支負擔。

由此可見,向量運算有非常明顯的優點:

一、向量處理流程比傳統的「純量」(Scalar)運算,可避開修改迴圈控制變數與條件判斷。請別忘了泛用 CPU 的世界,還有讓人感到極度噁心「分支傷害」、「分支預測」與「分支預測錯誤的折損」。

二、因一個指令就可做到數十、數百個指令才能完成的運算,減少指令數,可節約反覆從記憶體擷取指令並解碼再執行的頻寬及時間,利於打造複數執行管線架構。拜「運算方向固定」與「不同向量運算指令之間,並無控制流程相依性」之所賜,也較易於打造更深的指令執行管線。

相對於多執行緒的 GPU,向量電腦採取截然不同的方法隱藏記憶體延遲,藉由記憶體與向量暫存器之間的區塊傳送,向量載入與儲存都只付出一次性的延遲。

三、記憶體存取模式與行為也是固定的,不需要考慮太多特殊情況,如少量卻頻繁的隨機存取,也降低了設計最佳化記憶體系統的門檻。

但俗語說的好,魔鬼藏在細節內,抽絲剝繭後,你才會看到向量電腦真正的奧妙之處,以及 GPU 以不同奇計淫巧繼承而來的特色。

首先,程式同時需要長短不一、在執行期間會受到變更的向量長度,該怎麼辦?這時候向量長度暫存器(VLR,Vector-Length Register)就派上用場了,編譯器設定 VLR 的值,就可以控制任何向量運算的長度(當然,不能超過向量暫存器的最大長度),包含載入與儲存。

這更意味著向量電腦極為重大的優勢:向量暫存器的長度可以在後來的產品世代繼續成長,不需要變更指令集,就可持續提昇計算能力,但反觀受制於現有 CPU 指令集編碼格式與暫存器數量限制的 SIMD 多媒體指令集,每當變更向量長度,就得大興土木,疊床架屋個幾百個指令(如你感到好奇,可自行拿起計算機算算 Intel 從 MMX 到 AVX-512 增加多少 SIMD 指令)。

GPU 則是將透過硬體機能,將巨大的向量長度,拆散到數以萬計的暫存器,沒有這樣的困擾。

更何況,GPU 因具有 I/O 裝置的特質,提供了介於編譯器和硬體之間的間接性,讓 PTX 變成與底層硬體脫鉤的虛擬指令集(類似 Java 的 Binary Code),而非會綁死相容性的二進位機器碼,日後要「動搖國本」,難度也遠比 CPU 簡單,像 nVidia 與 AMD 歷代 GPU 微架構多年來吃飽沒事基因突變,但也完全沒有影響到軟體堆疊,驅動程式品質就再看看了。

其次,所謂「博觀而約取,厚積而薄發」,我們需要指定一道向量指令內,替向量迴圈中的每一個元素運算進行條件式執行,例如:先對 1 3 5 元素作加法,再讓 2 4 6 元素作減法,接著再讓剩下的元素作乘法,該怎麼作?向量遮罩暫存器(Vector-Mask Register)就堂堂登場了,任何被執行的向量指令,只會處理向量遮罩暫存器中那些被指定為 1 的元素,而被指定為 0 的元素則不受任何影響。

乍看之下,編譯器讓遮罩中充滿了大量的 0 是非常浪費運算效能的蠢事,但這種設計消除了傳統泛用 CPU 的分支處理與控制相依性,速度反而更快。很不幸的,基於和無法「不需要變更指令集,就可以提昇向量處理效能」的相同理由,SIMD 多媒體指令集多半沒有這樣的設計。

那需管理數以千計 Stream Processor 的 GPU 有沒有向量遮罩暫存器呢?答案是:有,但是你看不見,GPU 是用內部硬體功能提供向量遮罩,遮蔽掉特定的 Stream Processor,而不像向量電腦是讓軟體編譯器去直接操作暫存器。

最後,向量電腦一次性從散落在記憶體各處的運算元素「聚集」至向量暫存器內,運算結束後再一次性「分散」回記憶體四處,記憶體子系統需同時處理多個記憶體載入與回存的能力,大量獨立運行的 Memory Bank 與預先擷取機能,指令集也需提供索引(Index)式載入與儲存等精巧的定址模式,增加向量編譯器能夠將程式碼向量化的機會,儘管執行起來通常遠比非索引的狀況慢得多。通常向量電腦會配置專屬的控制處理器(Control Processor)來輔助,如為索引式載入與儲存,自動遞增記憶體位址。

論記憶體子系統,Cray 在 2002 年發表 Cray X1 向量運算超級電腦所採用的 Multi-Streaming Processor(MSP)是很鮮明的案例:一個 X1 節點,由四組 MSP、16 組記憶體控制器與 32 片記憶體卡板所組成。

並不是把一堆處理器核心硬塞到單晶片內,看起來有很好的帳面理論運算效能,就可稱之為「單晶片超級電腦」,空有運算效能沒用,內部的匯流排與記憶體子系統更需密切配合以克竟全功。至於時下 GPU 記憶體子系統的效能水準,除了延遲很長,相信就沒有太多需要特別挑剔的地方了。

所有載入都是聚集、所有儲存都是分散的 GPU,GPU 程式設計師需保證所有聚集中和分散中的所有位址,都是指向相鄰的位置,GPU 硬體中扮演著跟向量電腦控制處理器相同角色的「執行緒區塊排程器」,需在執行期間辨認出這些位址的序列,確認他們是否相鄰,將聚集與分散,轉變為高效率的跨度式記憶體存取。

泛用 CPU 的 SIMD 多媒體指令集上的聚集分散式記憶體存取呢?很抱歉,原先幾乎沒有這些寶具,是近期才慢慢的補完。以 x86 指令集為例,演進如下,效能怎樣,在此不做評論:

  • 2011 年 1 月:Sandy Bridge 微架構:AVX 指令集剛問世時,沒有聚集和分散指令。
  • 2011 年 6 月:Xeon Phi x100 系列(Knights Corner):其 VPU 指令集(IMCI,Intel Many Core Instructions)提供聚集和分散指令,但 Xeon Phi x100 只能作為輔助處理器,不能執行 x86 指令。
  • 2013 年 6 月:Haswell 微架構:AVX2 指令集新增聚集指令。
  • 2013 年 6 月:Xeon Phi x200 系列(Knights Landing):要直接跟 GPGPU 打對台,就得硬著頭皮全上了。
    1. AVX-512F 指令集同時支援聚集與分散指令。
    2. AVX-512PF 指令集增加聚集與分散的預先擷取(Prefetch)版本。
    3. AVX-512CD 指令集增加偵測位址衝突(Address Conflict)的分散指令。

一路看下來,SIMD 三種型態擺在一起比比看,受制於現有 CPU 指令集的包袱,相較簡潔優美的向量電腦和仰仗先進硬體承先啟後的 GPU,帶有強烈「附贈」色彩的 SIMD 多媒體指令集看起來似乎有點廢廢的,但也並非毫無一無可取之處,因近代多工作業系統的迫切需求,虛擬記憶體管理就是 CPU 最強的地方,尤其是按需求分頁(Demand Paging)的功能,也是 GPU 雙雄努力補強中的弱點。

如何從「多執行緒 SIMD」的角度來檢視 GPU 的全貌?

為方便讀者理解,這裡舉兩個範例,以求公平,nVidia 和 AMD 都得被筆者拖上台現場表演給大家看,推廣 CUDA 已久的 nVidia 戲分一定會比較多。

nVidia G80(Tesla 1.0 微架構,GeForce 8 系列)家族執行 CUDA 時,一個多執行緒 SIMD 處理器(SM,Streaming Multiprocessor),包含 8 個 Stream Processor(SP,又稱為 CUDA Core),此外還包含 8,192 個暫存器、16kB 共享區域記憶體與共用的快取記憶體,如常數、材質等。每個執行緒對應一個 Stream Processor(有些文章將此翻譯為「流處理器」或「串流處理器」,但筆者偏好沿用原文)。

CUDA 的執行緒有三個階層,對應 GPU 的硬體層級,由大到小:

這裡需要特別注意:從 CUDA 的程式模型角度來看,8 個 Stream Processor 組成是四個一組,實際上可看成兩組 4D 的 SIMD 處理器。

為什麼 4 個一組?道理也很簡單,3D 影像的「顏色」和「位置」,都需要四個數值,分別是 RGB 三原色加上 Alpha 半透明通道、與 XYZ 三維座標與 W 遠近參數,各需要四次運算。同理可證,這也是 AMD 近代 GPU 的底層運算單元是 4D + 1D 或 4D 的緣故,而不是像啥 5D 6D 7D 這些乍看之下還以為是 Canon 單眼型號的模樣。

每個運算都最少有 4 時脈週期的延遲,起碼要執行 32 個執行緒(8 SP x 4 時脈週期)才可能隱藏運算延遲,初代 CUDA 以硬體自動分組、以 32 個執行緒為單位(Warp),「塞」給一個 SM。如轉換成「餵食」兩個 4D SIMD 處理器的角度,就是需要兩組 16 個執行緒,也就是兩組「半個 Warp」(Half-Warp)。

想得簡單一點,一個 Warp 代表畫面的一塊小方格。

所有執行緒被加以區塊化,並以 32 執行緒為組群而執行。如一個 Warp 內的執行緒碰到停滯,例如等待顯示記憶體,此時可切到另一個 Warp 的執行緒,掩蓋記憶體延遲。一旦區塊內的執行緒並非 32 的倍數,SM 的執行緒排程器會將剩下的執行緒包成一個 Warp,浪費 GPU 的計算能力,這是開發 CUDA 程式時需要特別注意的地方。

同一個 Warp 內的執行緒,將「執行相同的程式碼」,但「處理不同的資料」,這時候,你就看見鬼影幢幢的 SIMD 靈魂了。

但執行緒的數量受制於暫存器總量,G80 一個 SM 總計有 8,192 個暫存器,假如一個執行緒佔用 16 個暫存器,單一 SM 的執行緒上限是 512(512 執行緒 × 16 暫存器=8,192),等於 16 個 Warp,如一超過,就需要將一部分的資料搬移到 GPU 外部的顯示記憶體,降低執行效率,在撰寫 CUDA 程式時,並不能無止盡的增加執行緒的數量,而共享的資源,如區域記憶體和快取,也是開發程式時需深思熟慮之處。

事實上,每個 SM 可以管理的區塊和執行緒都有其上限,也跟著 GPU 微架構世代而演進,例如:

  • Tesla 1.0(G80)是 8 個區塊、768 執行緒(24 Warp)
  • Tesla 2.0(GT100)是 8 個區塊、1,024 執行緒(32 Warp)
  • 後來的 Fermi 增加到 8 個區塊、1,536 執行緒(48 Warp)
  • Maxwell 之後到 Pascal 激增到 32 個區塊、2,048 執行緒(64 Warp)

對技術再不敏感的讀者,在這裡也可以察覺一個顯而易見的殘酷事實:對 GPU 底層架構不夠熟悉,根本寫不出像樣的高效率程式,充分榨乾 GPU 的運算潛能。

GPU 雙雄如何定義如此詭異的運算架構?

覺得 G80 太老舊?那我們瞧瞧引領 nVidia GPU 更大幅接近主流泛用 CPU 的 Fermi 微架構(GF100,GeForce GTX 480),其 SM 組成結構如下:

  • 兩組 16 個Stream Processor(CUDA Core)組成的 SIMD 運算單元,總共 32 個,當然你可以把 16 個 SP 看成 4 個 4D SIMD 處理器。
  • 16 個載入/儲存單元,一個時脈週期內最多可以執行 16 個執行緒。
  • 4 個特殊功能單元,計算像平方根、倒數、sine 和 cosine 等三角函數。
  • 32768 個 32 位元寬暫存器。
  • 暫存器和記憶體都具備 ECC 糾錯機能。
  • 64kB SRAM,可設定為「16kB L1 資料快取記憶體+48kB 區域共享記憶體」或「48kB L1 資料快取記憶體+16kB 區域共享記憶體」。
  • 所有 SM 共用 768kB L2 資料快取記憶體,這讓 Fermi 長得更像 CPU。

觀念等同於「多執行緒 SIMD 處理器」的 SM,其 Stream Processor 與暫存器數目,隨著不同世代的 GPU 微架構而有所更動(如 Fermi 是 Tesla 1.0 的四倍),以 Fermi 為例,任何一個指令都最少需要兩個時脈週期來完成,套用 G80 的狀況,等於是需要塞一個打包後的 32 執行緒(也就是前面提到的 Warp),給 16 個 Stream Processor 組成的 SIMD 運算單元,而且要保持滿載,一次要塞兩個。

為改善硬體使用率,Fermi 微架構的每個 SIMD 處理器,都擁有兩個執行緒排程器(也就是負責切 Warp 的苦主)與兩個相對應的指令分派單元,在每兩個時脈週期內,從每個執行緒派發一道指令給運算、載入儲存與特殊功能單元。

這就是 SIMD 運算結構與「前仆後繼」的多執行緒兩者結合而來的威力,nVidia 將 CUDA 程式設計模型,命名為前所未見的「單指令多執行緒」(SIMT,Single Instruction, Multiple Thread),而 AMD 則稱之為單指令多重執行樣板(SIMI,Single Instruction, Multiple Instance),實際上講的是一模一樣的概念,但撰寫計算機結構教科書的大師和開班授課的教授心裡怎樣五味雜陳,我們就不得而知了,畢竟 CPU 和 GPU 在計算機結構的家譜中,並沒有共同的祖先。同場加映 AMD GPGPU 的技術基石 GCN(Graphic Core Next)。在 GCN 問世之前,AMD GPU 的 Stream Processor 是四個綁在一起的 VLIW4 結構,一道指令同時用到這四個 Stream Processor,如須發揮最高利用率,編譯器需最佳化排程設法塞好塞滿。但 GCN 可同時執行四個執行緒,一道指令僅用到一個 Stream Processor,如果指令都可以在一個時脈週期內完成的話,也可以用好用滿。

爬文至此,相信各位看倌堆積在臉上的營業式笑容,已經轉化成一陣陣抽搐的嘴角,附帶著劫後餘生的表情。我們現在進入主題:GPGPU 是什麼。

GPGPU 是什麼?

GPGPU(General Purpose computing on GPU)直接翻譯為「圖形處理器通用計算」,講白話一點,就是讓 GPU「不務正業」,去做和傳統繪圖無關的通用計算任務,特別是適用於單指令多數據流(SIMD)的高密度浮點運算。

GPGPU 並非 GPU 與生俱來的「本能」,而是隨著 GPU 引進以著色器微中心的可程式化繪圖管線、陸續支援標準 32 位元單精度與 64 位元倍精度浮點標準並符合 IEEE 754 規範(後來 IEEE 754-2008 再加上浮點乘積和)後,才慢慢蘊含通用運算的潛力。

整體來說,GPU 適合一次進行大量相同的運算。CPU 則較有彈性,能同時進行變化較多的工作。兩者相輔相成,沒有哪邊可以徹底取代對方的可能。

對比「泛用」的 CPU,使用 GPU 來進行運算工作,主要有幾個潛在的優勢:

  • 更巨量的執行單元:以 nVidia 最高階顯示卡 Titan Xp(GP102-450)為例,內含 3840 個 Stream Processor,時脈約 1.5GHz,32 位元單精確度浮點數的最高理論效能高達 12Tflops。高效能泛用 GPU 雖然有更高的時脈,但執行單元與理論運算效能卻遠遜於同時期的 GPU,而且 GPU 多半仍採用較主流桌上型處理器和伺服器 CPU 落後的製程。不意外,CPU 的電晶體大多數都砸在控制單元和快取記憶體了。
  • 更巨大的記憶體頻寬:前述的 nVidia Titan Xp 有 547.7GB/s 的理論記憶體頻寬,而配置 HBM2 記憶體界面的 Tesla P100 16GB 版本是驚人的 720GB/s,Tesla V100 更是驚世駭俗的 900GB/s,反觀世界上最高階的伺服 器CPU,如 IBM Power9,裝上 Memory Buffer,最多也「僅」230GB/s(沒 Memory Buffer 時,8 通道 DDR4 會減半成 120GB/s),更不用提 Intel Xeon 和 AMD EPYC 這些 x86 便宜貨了。
  • 和高階 CPU 相比,價格遠較低廉:例如一張 Pascal 微架構的 Titan Xp 包括 12GB GDDR5X 記憶體的價格,「才」1,200 美元,而 Intel Xeon 的旗艦 8180M 一顆就 13,011 美元,足足可以買 10 張還有得找,相信各位「礦工」對此特別有感。

當然,天底下沒有白吃的午餐,GPU 也有它的缺憾:

  • 平行不夠高,效能不會好:GPU 的運算單元數量很多,不能高度平行化的工作,所能帶來的效益就不高。
  • 浮點不夠準,整數不夠快:礙於成本和效能,GPU 通常只支援不符合 IEEE 754 的 32 位元單精確度浮點數, 有些運算的精確度可能較低(這對重視運算輸出結果的高效能運算很傷)。nVidia 是遲至 Fermi 世代的 CUDA compute compatibilty v2.0,才算完備 IEEE 754,但很多硬體加速的數學函式,其輸出結果,並不保證與 CPU 一致。

此外,許多 GPU 並沒有獨立的整數運算單元,整數運算的效率較差,偏偏人工智慧和深度學習(可視為類神經網路換個稱呼)仍是以整數運算為主的應用,我們將會在後面看到 nVidia 在踏上人工智慧之路前,補強整數運算的罩門。

  • 只適合一路油門踩到底:GPU 通常沒有分支預測等複雜的輔助流程控制單元(就算有,也會很慢),對分支密集、大量條件判斷的應用程式,如資料庫,效率會比較差,而且是非常差。
  • 記憶體容量受限,升級不易:GPU 都會搭配高頻寬(加上高延遲)的記憶體,如 GDDR,但如要處理更大更複雜的問題時,仍需要更多的記憶體容量,在增加容量時保有高頻寬,並維護記憶體資料的可靠性,也是一大挑戰。當時下 CPU 可隨時擴充至 TB 等級的容量,nVidia Tesla P100 和V100 也僅杯水車薪的 16GB。

為實現高頻寬,GDDR 繪圖特化記憶體直接焊接在與 GPU 同一塊板子上,毫無日後升級的彈性(早期顯示卡還有辦法這樣作,現在就沒轍了),就無須浪費篇幅討論了。

  • 記憶體系統仍為化外之民:因多半以獨立 GPU 晶片與專屬顯示記憶體的形式存在,其外部 I/O 裝置的特性,也強迫資料需要在系統主記憶體與顯示記憶體之間搬來搬去。

nVidia CUDA 程式分為兩個部分:Host 端和 Device 端。Host 端是指在 CPU 執行的部分,而 Device 端則是在 GPU 執行的部分,Device 端的程式又稱為 kernel。通常 host 端程式將資料準備好後,複製到 GPU 的記憶體,再由 GPU 執行 device 端程式,完成後由 host 端程式將結果從顯示卡的記憶體中取回至系統主記憶體。由於 CPU 與 GPU 之間多半經由 PCI Express 溝通,降低效能在所難免。

「記憶體容量不足且難以升級」與「缺乏對 GPU 記憶體的直接存取」的缺陷,解決方案不外乎「讓系統和 GPU 共享統一的實體記憶體,或著在邏輯上是統一的、結合於單一的記憶體位址空間」。

以 AMD GCN(Graphic Core Next)的 x86 虛擬記憶體、與 nVidia 從 Pascal 開始支援的 Unified Virtual Memory為 例,簡單來講,就是將顯示卡上的 GDDR5,變成 CPU 可識別並直接存取的系統記憶體。AMD 在 2013 年籌建 HSA(Heterogeneous Systems Architecture)基金會時發布的 hUMA(heterogeneous Uniform Memory Access),則進一步讓 GPU 可以染指 CPU 那豐碩但速度差很多的系統記憶體容量。

  • 開發環境還不夠安定:GPGPU 的程式模型的成熟化與標準化在 2012 年之後才成型,早期  NVIDIA 和 AMD / ATI 就有各自不同的程式模型(一個 CUDA,一個 Stream),是經過多年發展與折衝,才勉強有現在的成果,要迅速發展適合 GPGPU 的應用程式,仍是相當有挑戰性的工作。
  • 難以一招半式闖江湖:相對「不分指令集架構,所有人只會越長越像」的 CPU,GPU 的微架構演進遠比 CPU 激進,這也意味著同一套程式最佳化手段,難以放諸天下而皆準,這也間接拉高 GPGPU 普及化的困難度,因為難以一次開發在所有 GPU 都可以跑很快的應用程式,對 GPU 底層了解不夠,就很難寫出高效率的程式碼。

nVidia 和 AMD 的 GPU 微架構大相逕庭,然後光 AMD 一個世代的產品線,就可以涵蓋三到四種不同時期的微架構,讓人挑產品時挑到想翻白眼,而「使用 Intel 的編譯器在 AMD 的 CPU 執行 SPEC CPU,也是可以跑很快,最佳化哲學都很類似」就沒有這樣的困擾。

萬丈高樓仆街起

恭喜各位,撐到現在,總算進入最受讀者歡迎的畫唬爛編年史時間了。

以硬體視角為中心,GPGPU 發展史,大致有以下里程碑,關於 GPGPU API(如 OpenCL)的細節,因就筆者個人觀點,整個 GPGPU 生態系統是 2015 年之後才接近成熟,在此不談,否則就沒完沒了。

GPU 通用運算的醞釀期:2000 年至 2006 年。

  • 2000 年 11 月 12 日:微軟發布 DirectX 8.0,可程式化繪圖管線的 Vertex Shader(頂點著色器)與 Pixel Shader(像素著色器)開始吸引眾人眼球,將焦點聚集在顯示晶片廠商和遊戲開發者將如何接招的好戲。
  • 2001 年 2 月 28 日:nVidia 發表全世界首款對應 DirectX 8、150nm 製程的 GeForce 3(NV20),也難逃多數晶片設計商的宿命:全新架構尚未成熟的產品常常舉步維艱,而 GeForce 3 Ti 500 系列可改電阻升級成 Quadro 專業繪圖卡的神蹟,更讓人嘖嘖稱奇(感謝熟識的光華店家幫忙操刀,筆者有幸躬逢其盛此精神上的勝利)。

值得一提的是,初代 Xbox 的整合繪圖晶片組 NV2A 是 NV20 的衍生物,能做成 nForce 晶片組來賣,肯定是不得了的大事,當然這件好事沒有發生,Intel 絕不會讓此事成真。

  • 2002 年 11 月 18 日:經過多次延宕,nVidia 發表 130nm 製程的 GeForce 5(NV30),為 CG 程式語言與 DirectX 9 的 Shader 2.0,外掛 nVidia 自行擴充的 Cine FX 著色器功能、與 32 位元浮點精確度,讓 NV30 的電晶體數量激增至前代的兩倍,加上尚未成熟的 GDDR2 記憶體,造成極為嚴重的高熱問題,而僅僅 128 位元的記憶體界面寬度,更成為限制其效能表現的緊箍咒,最後慘遭「精簡設計哲學」的 ATI Radeon 9700 / 9800(R300)迎頭痛擊。

嚴格說來,NV30 跟 GPGPU 毫無瓜葛,但筆者不得不在此特別拖出來遊街示眾品頭論足一番:

  • 微軟決定遊戲規則的影響力:nVidia 萬萬沒想到 DirectX 9 的 Pixel Shader 竟然開了一個「FP24」的後門,讓 ATI 可以用比較低的像素浮點精確度,硬拚更高的運算效能,讓 FP16 和 FP32 二選一的 nVidia 裡外不是人:16 位元精度品質不太好,32 位元精度速度又太慢。
  • 遊戲與通用難以兩者兼備:和個人電腦的 CPU 一樣,GPU 先以遊戲優先的繪圖市場為首要設計考量,「兼差」過頭,隨時可能在激烈的市場競爭中意外翻船,這也是限制 GPGPU 發展的潛在關鍵因素,Tesla 2.0 後的 nVidia 和 Southern Island 後的 AMD,都採取「先不傷身體,再講求效果」的保守路線。

我們繼續往下看 nVidia 和在 2006 年 7 月併購 ATI 的 AMD,在 2006 年直到 2012 年的草創時期,兩邊一來一往,你揍我一拳我踹你一腳你尻我一棒我捅你一刀的激烈交鋒。

  • 2006 年 8 月 23 日:為高效能運算市場,以 Radeon X1800(R520)為基礎再設計,AMD 第一世代「Stream Processor」首款產品 Radeon X1900 XT 系列(R580)首度支援 32 位元單浮點精確度。

DirectX 10(Direct Compute 4.x)/OpenGL 3.3:統一著色器架構與 64 位元雙倍浮點精確度。

  • 2006 年 11 月 9 日:nVidia 耗費近 5 億美元研發經費與 4 年光陰,世界首款對應 DirectX 10 統一著色器(Unified Shader)架構,支援 32 位元單浮點精確度的 GeForce 8 系列(以 G80 為首的 Tesla 1.0 微架構),初代 CUDA 的載具,堪稱是 nVidia GPU 微架構史上最大的突破,也是 nVidia 正式邁入 GPGPU 的起點(筆者心目中的原點其實是 NV30,但絕對會被鄉民罵翻,想想還是算了)。

nVidia 併購 AEGIA 而來的 PhysX 物理引擎,也成功移植到 CUDA,也代表 G80 之後的 nVidia GPU 均可讓坐在電腦前面的人有機會「親自體驗如強烈的爆炸、具有互動反應的碎片、逼真的流水,以及栩栩如生的角色等動態」。

而揚棄過往向量化的運算方式,後來改名為 CUDA Core 的 Stream Processor(SP)將所有著色器運算通通拆成 1D 純量,以求更好的執行單元利用效率、並以高速兩倍以上時脈運行(有沒有讓你想到Intel Pentium 4 的兩倍時脈整數運算器?),也讓 Tesla 1.0 看起來更接近一般的泛用處理器。

Tesla 1.0 還有一個值得大書特書的里程碑:nVidia GPU 的匯流排純 PCI Express 化,甩開 AGP 過渡期,這對 GPGPU 應用也帶來潛在的助益。

關於 G80 最有趣的八卦:nVidia 保密極度徹底,發表前其他競爭對手的 NDA 產品時程表和規格比較表,完完全全認定 G80 僅為分離式著色器 G70 的演化版,連當時任職於某 IT 週刊的筆者自己都不小心上當,相信下巴差點掉下來的受害者絕不只筆者一人。

  • 2007 年 5 月 14 日:AMD 初次對應 DirectX 10 與統一著色器架構的 Radeon HD 2900(R600,初代 VLIW5 的 TeraScale 微架構)首度支援 64 位元雙倍浮點精確度,但其效能僅單精確度的五分之一,而走上「超大+超熱+超貴=超生」之路的 R600 家族也中斷了 AMD「恐龍化」GPU、轉向「兩顆打一顆」的設計路線。

  • 2008 年 6 月 1 日:以 Tesla 2.0 之首 GT200 為基礎、對應 DirectX 10.1 與 CUDA 1.3 的 Tesla C1000 系列成為 nVidia 首款支援 64 位元雙倍浮點精確度的 GPU,但效能也僅單精確度的「十二分之一」。

著色器分頻──更精確一點,是讓「多執行緒 SIMD 處理器」的時脈遠超過核心時脈──從 GT200 開始,比例固定為核心的兩倍。

  • 2008 年 6 月 25 日:開始支援 OpenCL 1.1 的 AMD Radeon HD 4800 系列(R700)創下單晶片 32 位元單浮點精確度理論效能達 1Tflops 的里程碑,而繼承 RV670、率先支援 GDDR5 記憶體的 RV770,因兼備效能與價格競爭力,則成為 AMD 顯示晶片發展史上罕見的巨大成功。

此外,因 HD 4770 讓 AMD 提早「淺嘗」台積電 40nm 製程,避開了 nVidia 在 Fermi 世代因 40nm 製程陣痛期遭遇的麻煩。

DirectX 11(DirectCompute 5.0):完整的 IEEE 754-2008 標準與浮點乘積和指令(FMA)。

比一比這時期的 GPU 雙雄主力,雙方的微架構差異性,一目了然,nVidia 高時脈極致效益,AMD 低時脈人海戰術。但假以時日,「假設」某方突然兩者兼備面面俱到,市場的恐怖平衡,天平的一側就會瞬間倒向其中一邊。

  • 2009 年 9 月 23 日:AMD 的 Radeon HD 5000 系列「Evergreen」(第二代 VLIW5 TeraScale 微架構)世代在 DirectX 11 捷足先登,浮點運算規格「不得不」完全符合 IEEE 754-2008 的規範,AMD GPU 也開始支援 OpenCL 1.2。
  • 2010 年 3 月 27 日:因導入 40nm 製程不順,nVidia 推出「Fermi 不完全體」GTX 480(GF100),除了支援 DirectX 11,浮點運算規格也完全符合 IEEE 754-2008 的規範,也可進行單倍浮點精確度的乘積和(Tesla 2.0 只能作雙倍)。

從 Fermi 開始,nVidia 讓 GPGPU 專用的 Tesla 產品線使用 64 位元雙倍浮點精確度執行單元比例更高的高階核心,分而治之,讓一般消費型顯示卡和專用運算卡拖鉤,以防一般消費者不需要的「外掛」傷害產品競爭力。

  • 2010 年 11 月 9 日:「Fermi 完全體」GTX 580(GF110)誕生。開始正式進入 GPGPU 世界的 nVidia GPU,從 G80 一路到 Fermi,OpenCL 都是支援到 1.1,1.2 是後面的故事。
  • 2010 年 12 月 15 日:「Northern Island」家族中 Radeon HD 6900(Cayman)系列引進 VLIW4 格式的第三代 TeraScale,將「四個簡單的向量運算單元(4D)加上一個專屬複雜特殊運算的單元」(T Unit),改造為「四個可處理所有工作的運算單元」(4D T Unit),改善指令排程與執行單元的利用效率,為 AMD 真正進入 GPGPU 的 GCN(Graphic Core Next)預作準備。
  • 2012 年 1 月 9 日:「Southern Island」家族採用 28nm 製程的 Radeon HD 7970(Tahiti XT)導入第一世代 GCN,AMD GPU 正式進入 GPGPU 的世界,雖然上市沒多久就慘遭 nVidia 的 Kepler 微架構海扁一頓,但也開啟了 AMD 第一次挖礦奇蹟。

nVidia 和 AMD 的製程微縮皆「黏」在台積電 28nm 很長一段時間,直至 2016 年中旬。

從此之後,nVidia 與 AMD 就手牽手一同過著幸福美滿共同瓜分市場的好日子?

才怪。

打開 GPGPU 這個潘多拉的盒子後,要兼顧現有遊戲繪圖市場與「前途似錦」的通用運算應用,求不傷業績再講求願景,才是對 nVidia 和 AMD 最嚴酷的考驗,兩邊的實力消長也就此展開序幕,直至今日 nVidia 在市場佔有率甩開 AMD 的現況。

擺盪於「現在」與「未來」的翹翹板

同樣立足於個人電腦市場的巨大地基,GPU 走向 GPGPU 的軌跡,極度近似 x86 CPU 征服伺服器市場的歷程,藉由個人電腦市場的「量」獲取長期穩定發展的基礎與攤平研發成本的利基,也是 GPGPU 的最重要資產。

但現實生活告訴我們,「資產」和「包袱」是硬幣的正反兩面,一旦不小心油門踩到底衝過頭,無法善盡在「本分」保持卓越的責任,就會兩頭皆空,從 Fermi 開始,nVidia 不惜犧牲 64 位元雙倍浮點精確度的效能,也要小心翼翼地確保現有遊戲市場的競爭力,謹慎地微調多執行緒 SIMD 處理器的資源分配,就是最好的例證(被迫困死在台積電 28nm 製程也是原因之一)。

進入GPGPU 世界後的 nVidia GPU 之「多執行緒 SIMD 處理器」Streaming Multiprocessor,內部運算執行單元配置,簡單整理如下,特殊功能單元等細節就不談了。

  • 2012 年 3 月 22 日:GeForce GTX 680(GK104-400),28nm 製程 Kepler 微架構的首發,堪稱是 AMD 一連串惡夢的開端。nVidia 在 Kepler 世代做了幾件很重要的創舉:
    1. 可能是被出師不利的 Fermi 燙到了,改變過去先推出旗艦晶片再一路往下砍功能單元的產品推出節奏,新型微架構先搶灘登陸中階市場,結果萬萬沒想到顯示卡市場就此轟動上演了「中駟 KO 上駟」的歡樂脫線劇場,nVidia 原先設定的中階不小心打爆了 AMD 的高階產品,極可能連 nVidia 自身也始料未及,AMD 就這樣莫名其妙一蹶不振。
    2. nVidia 放棄了從 Tesla 2.0 開始的著色器兩倍時脈分頻,將提高時脈的投資,轉向激增執行單元密度,核心編號「中階」的 GK104 的 Stream Processor 數量竟高達 GF100 的三倍,改名為 SMX 的 SIMD 多執行緒處理器,就包了 192 個 Stream Processor,整整是 Fermi 的 6 倍,暫存器也加倍至 65,536 個(吃了威而剛的 GK210,更倍增到 131,072 個暫存器)。
    3. 以後見之明來看,在 Kepler 之前,nVidia 的以高時脈純量執行單元利用效率見長,AMD 則猛堆 VLIW 執行單元以量取勝,但 Kepler 卻像冷戰末期的蘇聯水下核能攻擊潛艦一樣的質量俱佳, AMD 沒能馬上追咬,被 nVidia 一舉打垮,一點都不讓人感到意外。
    4. 因應激增的執行資源,SMX 的執行緒區塊排程器倍增到四倍,指令分派單元從兩個變成八個。
    5. nVidia GPU「終究」也有類似 CPU 的 Turbo Boost 動態超頻,雖然那個超頻幅度,連主機板偷偷打開超頻模式都還不如(還有骨灰玩家記得陞技的 2.5% 事件嗎?)
    6. 但家用版 Kepler 的 64 位元雙倍浮點精確度的效能比例,卻從 Fermi 的八分之一,劇降至廿四分之一,擺明想靠激增的執行單元「以量取勝」,用三倍的值執行單元去填補三分之一的降幅,但取消著色器分頻的損失就得利用其他架構性的效率強化來彌補了。善男信女誠心誠意亟需高效能雙倍浮點?請認命掏出白花花的鈔票購買 GK110 和 GK210 的 Tesla 運算卡。
    7. PCI Express 3.0,不解釋。

nVidia 這致命一擊究竟何等沉重?有板卡大廠高階主管私下贈送筆者一片 Radeon HD 7970,筆者就毫不猶豫的黑貓快遞轉贈給台南友人,背後的千言萬語,一切盡在不言中,不想跟電費過不去。

總之,AMD 就在獨立顯卡市場的勢力版圖節節敗退,一路苦戰至 2016 年,偶爾靠著優異的挖礦效能,才勉強稍有起色。相信各位不會不理解,筆者在此不願排兵佈陣品頭論足,這段 AMD 被 nVidia 逼到懸崖邊緣、令人不忍卒睹的黑暗時期產品線。

談到挖礦,就不得不岔題一下 AMD 第一代 GCN 曾經享有的壓倒性優勢:比特幣基於 SHA256 的雜湊計算(Hash,從資料中建立較小的「指紋」)會用到大量的 32 位元整數迴轉計算,好死不死,nVidia 要三道指令才能完成,AMD 只要一個指令就可搞定,總時脈數更遠低於 nVidia,結果一張 500 美元、2,048 個 Stream Processor 的 Radeon HD 7970 挖比特幣的效率竟然是 999 美元、2,688 個 Stream Processor 的 GTX Titan 近兩倍,連 Radeon HD 7790 這種表訂功耗只有 85W、連外接電源可能都不需要的低階便宜卡,挖比特幣都還比 GeForce GTX 680 快一大截。

時日至今,AMD 仰仗 GCN,依舊在密碼學應用優於 nVidia,不知是無心插柳柳橙汁,還是 AMD 研發團隊內部「不能說的祕密」(開發可以暗助自己賺外快的產品,想想也滿屌的)。在這裡出賣台灣水電工協會的不名譽會長,搶先爆破區塊鏈技術概觀連載將會深入探討 GPU 挖礦這個越來越火熱的話題。

問題來了,那筆者幹嘛不留下這張從天上掉下來差點砸死自己 Radeon HD 7970 來挖礦呢?這就是年輕時不懂事犯下的低級錯誤了,小朋友千萬不要模仿。

  • 2014 年 3 月 22 日:GeForce GTX 750 Ti(GM107-400),止步於 28nm 製程 Maxwell 微架構,從 149 美元的中低階市場踏出第一步,既然製程沒有重大改進,nVidia「精鍊」多執行緒 SIMD 處理器,膽敢號稱每個 Stream Processor 的效能是 Kepler 1.35 倍、能量效率更達 2 倍,是非常值得一看的重點。
    1. 改名為 SMM,nVidia 沒事改來改去,真的很煩。
    2. SMM 內的 Stream Processor 從 192 減少到 128 個,並切成四個各自擁有獨立 Warp 排程器和指令分派單元的32 SP小區塊,以改善利用效率。
    3. 以事後的效能表現來看,128 SP 的 Maxwell(SMM)和 192 SP 的 Kepler(SMX),其 SM 的效能是相去不遠的,別說 1.35 倍,應該是 1.5 倍,能在相同世代製程、且電晶體密度與時脈相近的條件,微調出這樣的成果,很不簡單,但換個角度,也許是 Kepler 太過揮霍了。
    4. 可是……瑞凡……64 位元雙倍精確度浮點的效率只剩下卅二分之一。更糟的是,連專用運算卡產品線也難逃一劫,Maxwell 家族成為 Tesla 中效能最低者。除了 nVidia 將 Maxwell 定位成專攻消費市場的過度時期微架構外,沒有其他的可能了。
    5. 在相同的「預算」框架中,勢必有所取捨,Maxwell 就犧牲了 GPGPU 應用中高效能運算的環節。
    6. nVidia 推出砍功能的 Maxwell 產品時,也曾造成嚴重的風波:nVidia 砍掉 GM204 三個 SMM 的 GTX 970「3.5GB 顯存門」(因內部溝通出狀況,nVidia 行銷部門標錯 ROP 和 L2 快取的規格)事件,這裡不贅述,讀者有興趣可以自己去 Google 一下。

那 AMD 真的如此不堪?

從 2012 年初到 2016 年中旬,在 AMD 的 CGN 演進到第三代的過程中(基本上跟 nVidia 一樣,「黏」在 28nm 製程長達四年),對 nVidia 也並非毫無還手之力,在中小型規模 GPU 晶片都有不錯的表現,相信對顯示卡市場熟悉的讀者都還依稀記得 Radeon HD 7790(Bonarie XT,GCN 第二代)那極度優異的效能功耗,以及 Radeon R9(Fiji XT)搶先採用第一代 HBM 堆疊記憶體,造就可以塞入 Mini-ITX 小機殼的旗艦顯示卡,而 GPU 硬體協助補禎的 Fluid Motion 更是播放動畫影片的神器,筆者很納悶為何 AMD 這幾年來遲遲沒有好好的行銷、並堅定發展這麼實用的神兵利器。

平心而論,就 GPGPU 的應用角度,同時擁有 CPU 與 GPU 產品的 AMD,其精心打造的 GCN 是比較有遠見的設計,但整體而言,已主宰所有遊戲機繪圖晶片市場且長期在筆電市場較 nVidia 為優的 AMD,在高效能運算、專用繪圖領域與高階遊戲繪圖這些高獲利應用,不敵 nVidia 是不爭的殘酷事實,況且 AMD「擅長」在中低價位產品反覆進行換湯不換藥的更名,導致一個產品系列動輒「三代團圓,四代同堂」,也對產品行銷推廣(以及耗費大量時間考證產品系譜的倒楣筆者)與消費者造成莫大的困擾。

AMD 在繪圖晶片的佔有率在 2015 年曾崩盤到 18 趴的最低點,失去的領土,當然就自動投懷送抱成 nVidia 的囊中物,直到 2016 年 14nm 製程的 GCN 第四代「北極星」(Polaris)才漸有起色(但功耗控制看來還有不少小毛病,Vega 也是),回到 35% 的水準,而近半年來因挖礦熱潮,搞到眾多遊戲玩家有錢還買不到 AMD 顯卡的鬧劇,就不須浪費時間描述了。

因立志保護北極熊播被迫放棄多年 Folding@Home 轉而重視影片播放品質、夜奔敵營叛逃 AMD 的筆者,唯一的願望是:請 AMD 好好跟顯示卡廠商調控市場價格,不要再出現「台幣美元 40 比 1」的神奇匯率(反觀 nVidia 價格一直控制得很好,令人納悶 AMD 為何做不到)。

低精度浮點整數都要兩者兼備,才夠資格染指人工智慧與深度學習

GPU 在以浮點運算為主的高效能運算市場站穩腳步是一回事,但要搶救工人智慧於水深火熱之中的人工智慧與深度學習又是另一回事,模擬類神經網路不僅不需要高精度資料,16 位元半精確度(FP16)、16 位元整數(INT16)與 8 位元整數(INT8)足敷需求,更渴求高效能的整數運算能量,並兼顧節約記憶體消耗量。

近期 Intel Xeon Phi x200 的新版本「Knights Mill」相較於現有 Knights Landing 的規格修訂,是很好的參考範例。但晶片廠商能否在驅動程式層,隨即提供砍半精度給 DirectX、OpenCL 與 Vulcan 等 API 使用,那又是另外需要尋寶的目標了。

以 Pascal 微架構為起點,nVidia 讓 GPU「劈腿」的程度,拓展到另一個更加神奇的全新疆域。

  • 2016 年 3 月 5 日:GeForce GTX 1080(GP104-400)帶頭的 Pascal 吹響了眾多重大革新的號角,nVidia「擺脫」了糾纏 4 年的 28nm 製程,採用 16nm(2017 年的低階產品則躍進到 14nm)製造,還附帶不少嶄新的功能。
    1. 連爺爺您回來啦……不對,高效能 64 位元雙倍精確度復活了,Pascal 開始為其配置與 32 位元單倍精度各自獨立的專屬浮點運算器(但在實際實作層面,兩邊是否共用部分資源就不得而知了),高階晶片(GP100)重回 Fermi 時的 1/2 比例。
    2. Pascal 的一般運算 CUDA Core 被拆成兩種:
      • 32 位元/16 位元,浮點整數兼用。後期的 GP102 / GP104 / GP106 追加 8 位元整數與相呼應的內積向量指令(Vector Dot Product),開 nVidia GPU 之先河。
      • 64 位元浮點。
    3. 針對工人智慧……人工智慧,支援 FP16 半精確度浮點,可以想成現有 32 位元浮點運算器和暫存器一次處理兩個 16 位元。
    4. 導入 HBM2,讓 GP100 的記憶體理論頻寬一舉達到 720GB/s 的歷史新高。
    5. Pascal 開始支援統合 CPU GPU 記憶體定址空間並提供需求分頁的 Unified Virtual Memory,64 位元浮點加法指令可操作全域記憶體中的資料,事隔多年,在統一記憶體定址空間的機能,nVidia 終究擁有足以對抗 AMD 的武器,但筆者印象中這是本來就該在 Maxwell 粉墨登場的主角。
    6. 連接 IBM Power8 與 GP100 的「數據高速公路」NVLink 1.0,號稱有 PCI Express 3.0 的 5 到 12 倍傳輸效能。
    7. Streaming Multiprocessor 重新正名最早的 SM 簡寫,讓人頗有早知如此何必當初之感,SM 內部的 Stream Processor 組織結構再大風吹,從 Maxwell 的 4 塊變成 2 塊。
    8. nVidia DGX-1 深度學習系統,台大資工被贈與一台。

在 nVidia 最早公佈的產品時程表中,Maxwell 後面緊跟著 Volta,並沒有 Pascal 的存在,不過當仔細檢視真正為人工智慧和深度學習量身訂做的 Volta 後,就不難理解 nVidia「亂入」Pascal 的理由,這確實是如假包換的嶄新 GPU 微架構,企圖一次到位的風險實在太大了。

  • 2017 年 6 月 21 日:直接以 Tesla 產品線首發的 Tesla V100(GV100)是以台積電 12nm 製程打造、電晶體多達 210 億、包含 5,120 個 Stream Processor 的巨獸,HBM2 讓理論記憶體頻寬值逼 1TB/s 大關,NVLink 2.0 則提供接近前代兩倍的傳輸率。
  • 最重要的是,前面提到 GPU 在通用運算上的諸多缺陷,在 Volta 微架構幾乎消失無蹤。
    1. 獨立的整數運算單元:Volta 將原本 Stream Processor 內與浮點並存的整數單元獨立出來,額外配置和 32 位元單精確度浮點運算器數量相當的 64 個獨立整數運算單元,讓整數與浮點計算可同時進行。
    2. 換言之,Volta 用來作一般運算的 CUDA Core 有三種:
      • 32 位元 / 16 位元浮點。
      • 32 位元 / 16 位元 / 8 位元整數。
      • 64 位元浮點。
    3. 專用的深度學習浮點矩陣單元:nVidia 將適用於卷積(Convolutional )深度學習、如圖片特徵學習等應用的 4×4 浮點矩陣乘積和單元,命名為 Tensor Core(張量核心),每個 SM 配置 8 個。
    4. 更精細的執行緒資源分配:以往 nVidia GPU 將執行緒區塊切成由 32 執行緒所組成、共用程式計數器(PC,Program Counter)的 Warp,Volta 讓 32 執行緒都有自己的程式計數器,可實現更精細的 GPU 執行資源管理,不僅利於多工應用,更為未來更完善的 GPU 虛擬化造橋鋪路。
    5. 首創古老 CPU 才看得到的「L0」指令快取:大概是為保證前所未見超巨大 GPU 內部執行單元更加地車水馬龍,補上 L1 的 L0 指令快取,讓指令流更不容易斷線,讓筆者不得不懷念那 L0 指令快取加上指令資料共用 L1 快取的 Cyrix 6×86(M1),對上 Intel Pentium 與 AMD 5k86 資料指令分離式 L1 的設計優劣,還讓 BBS 連線硬體版爆發了幾場沒啥營養的筆戰。
    6. Unified Virtual Memory 共享記憶體位址補回 NVLink 的相關功能、SM 的 L1 資料快取/區域共享記憶體改回共用設計、SM 內部又像 Maxwell 一樣被大卸四塊等,相較之下,就沒那麼重要了。

不侷限於巨獸般的「人工智慧晶片」,nVidia 的自動駕駛產品線 Drive PX,最高階晶片 Xavier,內建了 512 個 Volta 微架構的 CUDA Core,宣稱可達成 1Tflops 僅需 1W 電力的能量效率。

那 AMD 呢?本文的 AMD 成分實在夠低了,再不聊聊最新的 Vega 微架構,恐怕屆時讀者留言又要再度「佳評如潮」,讓我們把望遠鏡對準織女星,一窺 AMD GPU 進軍人工智慧應用的棋局。

AMD 並沒有像 nVidia 大費周章特別為 GPGPU 和人工智慧,開發 GP100 和 GV100 之類的高規特別版,現階段只有和消費級產品共用相同晶片、取代 FirePro S 品牌的 Radeon Instinct 運算卡,但這並非表示 AMD 面向人工智慧世代的 GPU 就毫無看頭,實裝第五世代 GCN 的「Vega」(織女星)微架構,仍有值得重視的亮點,即使這些對一般消費者不必要的功能技術,AMD 會讓身為顯示卡的「正職」承受額外的風險與代價。

  • 2017 年 8 月 14 日:「簡報王」早在 2016 年底發佈 Radeon Instinct 運算卡,早已將技術細節全數自爆完畢的 Vega,終於不再只是簡報上技術行銷名詞的集合體。排除一般個人電腦玩家無緣一親芳澤的 nVidia GP100 與 GV100,由 Global Foundry 14nm 製程製造、125 億電晶體、4096 ALU(相當於 nVidia 的 SP)的織女星,是當下規模最巨大、通用運算與消費娛樂兼具的 GPU。
    1. Vega 的單一 CU(Compute Unit,相等於 nVidia 的 SM)由 64 個 ALU 組成,一個時脈週期處理 128 個 32 位元運算(64 個 32 位元浮點乘積和)。
      • 深度學習需較低精度的浮點與整數運算,Vega 可進行包裹式(Packed)計算,不僅FP16,亦含 INT16 與 INT8,因此每個時脈週期單一 CU 可作到:
        1. 128 個 32 位元(整數/單精度浮點)。
        2. 256 個16 位元(整數/半精度浮點)。
        3. 512 個 8 位元(整數)。
        4. 64 位元雙倍精度浮點,仍維持單精度 1/16 比例,可想成 8 個 64 位元。
        5. nVidia 並未在消費性產品下放高性能 16 位元運算,AMD 在此獨領風騷,但願不要哪天挖礦會用到,要不然遊戲玩家又要有錢買不到顯示卡了。
      • 鎖定 FP16 與 INT8 的應用,GCN5 新增約 40 個新指令,也為影像匹配此類深度學習應用,提供 SAD(Sum of Absolute Differences,絕對誤差和算法)指令,充分發揮單一 CU 每個時脈可進行 512 個 8 位元整數的特性。
      • 請努力回想一下多執行緒掩護延遲這個 GPU 極度重要的特色,思考 AMD 是怎麼做的。CU 內的 64 個 ALU,拆成 4 組 16 個,因運算延遲最短 4 個時脈週期,一次處理 64 執行緒的 Wavefront,等同 nVidia 的 Warp,也是螢幕上的一塊小方格。
    2. 重新設計後的記憶體控制器(HBCC,High Bandwidth Cache Controller)不僅支援容量更大速度更快的 HBM2 主記憶體,更提供高達 512TB 的定址能力,很明顯的,這絕對不是僅用來應付區區十來 GB 的 HBM2。
      • 為何會將主記憶體控制器命名為跟快取記憶體有關?因為 HBCC 可存取 SSD、網路儲存等外部記憶體元件,將 HBM2 視為超高頻寬的快取記憶體,對於開發人員,這些也是等同於顯示記憶體、可直接使用的空間。
      • AMD 去年在專業繪圖盛事 Siggraph 發表內建 1TB NAND 快閃記憶體的 Radeon Pro SSG,就是基於 Vega 的專業繪圖顯卡,也展示了不受顯示記憶體容量限制(16GB HBM2)、資料規模 TB 層級的專業繪圖渲染場景。
      • 還記得前面有提及 GPGPU 會面臨記憶體容量不足的限制嗎?AMD 讓顯示卡搖身一變成一台擁有多層次儲存空間的小電腦,的確是比與 CPU 共用虛擬定址空間更簡潔明瞭的作法,讓 Vega 更蘊含處理海量資料的本錢,與更彈性的 GPGPU 部署架構,更讓人好奇未來結合 Zen 微架構 CPU 的 APU 那引發無限遐想的可能性。
    3. 以上就是以單一晶片同時滿足消費與專業市場的前提,AMD 對人工智慧和深度學習打出來的牌局,但這也是兩面刃:如同筆者一再不厭其煩的暗示,Vega 目前差強人意的功耗表現,「受惠」於諸多凡人無感的「外掛」,這也是 AMD 需一關接著一關克服的瓶頸。

看在 AMD 手上擁有競爭力重返高峰 CPU 的份上,也許全新世代的 Fusion APU 才是專屬於滿手好牌的 AMD,唯一的最佳解答。

回首 20 年消費級 3D 顯示晶片來時路

這篇文章的初衷,最早是數年前,筆者準備動筆於某本已收攤的硬派電腦月刊的達人之路專欄,歷經一週煎熬,現在可以不遺留一絲一毫的遺憾。

消費性 3D 繪圖應用在個人電腦市場的發展,也只不過是近 20 年內發生的過往,從昔日的百家爭鳴,目睹眾多曾經獨霸一方的繪圖晶片廠商,像 2D 時代象徵 ET4000 的曾氏實驗室,視窗加速先驅的 868 、那美麗如藍寶石 IBM RAMDAC 的 968 、筆者人生第一張顯卡的心臟 Trio64V+ 的 S3,遊戲 3D 曙光期王者 Voodoo 傳奇的 3dfx,低價 3D 專業繪圖標竿 Permedia 的 3D Labs,以及舊時代貴族 Number Nine 等更多族繁不及備載的名廠,一間一間消逝於計算機工業的歷史洪流,令人感慨萬千。

20 世紀末期,看到 Intel 端出系出研發 F-22 和 F35 的 Lockheed Martin 的 i740(Auburn),不少電腦玩家還杞人憂天整個遊戲 3D 繪圖市場,最終會被 Intel 整碗捧去,所幸惡夢最後沒有成真。

反倒是 Parhelia 突圍失敗的 Matrox 現在還活得好好,筆者曾擁有過第一代 Millennium 和用來搭配 Voodoo 2 的 Mystique,在螢幕只有類比訊號輸入的年代,那眼見為憑高下立判的清晰訊號輸出,依舊讓人回味無窮。再回憶著當年週末沒事只能閒逛光華商圈的過去,ATI Rage 128 播放 VCD 時,那震撼人心的超高品質和豔麗色彩,記憶猶新,歷歷在目,「ATI 適合看影片」的招牌,至今仍被 AMD 的後代 GPU 們,有點完美又不完美的繼承著。

當年還是外文系文組白爛大學生的筆者,形單影隻佇立於現在八德路順發所在地 B1 現代生活廣場,某代理 Diamond 產品的店家前,隔著厚厚的玻璃牆,傻傻的凝視著搭載 nVidia 初代晶片 NV1、接上 SEGA Saturn 主機手把 Diamond Edge 3D,反覆跑著盤古開天世界遺產上古神獸的飛龍騎士,根本沒有料想十餘年後,這些古老 3D 顯示晶片的後代,高舉 GPU 旗幟,拓荒於通用運算疆域的未來。

讓我們期待下一個 20 年,多執行緒 SIMD 靈魂的 GPU,會讓我們翻閱多少頁賞心悅目的全新篇章,或著還是計算機工業又像銀河的歷史,再被撕掉一頁。這樣總結,對我的人生妥當嗎?

(首圖來源:shutterstock) 

關鍵字: , , , , , ,