為了能在不同的 NVIDIA GPU 上運作,CUDA 的執行架構實際上分為通用 (Generic) 與分化 (Specialized) 兩層,開發者撰寫好程式之後使用 NVIDIA C Compiler (NVCC) 產生供 CPU 執行的可執行檔與被稱之為 PTX (Parallel Thread Execution) 的語言檔案 (採用一種只有 NVIDIA GPU 能夠支援的組合語言),之後再由 PTX to Target Compiler 將 PTX 語言檔案編譯成各款 NVIDIA GPU 能夠執行的檔案 (目的是為了充分發揮不同 GPU 所具備的特性與功能)。
同時 PTX 這層共通介面的設計 (概念上跟 CPU 的指令集架構很像) 也是 CUDA 架構可以同時支援 CUDA C、DirectCompute、OpenCL 等 API 的主要功臣,當 NVIDIA 要加入對新種類 API 的支援的時候,實際上就是在 PTX 這層當中加入對該種 API 的優化與轉換機能。
Table of Contents
ATI Stream Technology
而 AMD 陣營當然也有與 CUDA 運算技術相當的技術 (不過可能知道的人比較少,AMD 一直都沒有很勤於宣傳這項技術),被稱之為 ATI Stream Technology,雖然 AMD 早在 2006 年就首創用 GPU 來跑 Folding@Home,但卻一直沒有很認真發展這項技術,因此直到 2009 年之前大多數人都認為 CUDA 沒有任何競爭對手。
ATI Stream Technology 的架構設計其實跟早期的 CUDA 很類似,同樣有著自家的程式語言與 API (稱之為 Brook,不過跟 NVIDIA 的 CUDA C Code 不同,Brook 是組合語言,很難寫,後來的 Brook+ 才改成高階語言) 與負責在程式與 GPU 之間中介的轉換層 (ATI 將其稱之為 Compute Abstraction Layer,計算抽象層) 等,不過由於知道的人太少,甚至後來 AMD 也不怎麼用 Stream Technology 這品牌,所以就不深入介紹了。
通用計算 API 的統一
不過在 CUDA 與 Stream 技術都出現之後,人們很快發現有個很嚴重的問題重演了,那就是各廠商之間的 API 竟又回到各自為政的情況 (甚至曾經出現一家用組合語言,另一家用高階語言的慘況),從過去經驗我們幾乎可以很直接的論定 API 不整合這技術基本上在未來只有死路一條,因此勢必得要有人出面推出大家共同遵守的 API 規範才行。
OpenCL
第一個跳出來主導開放 GPGPU API 的是由蘋果公司主導的 OpenCL (Open Computing Language,開放計算語言),在 2007 年開始發展,並且在 2008 年 06 月 16 日由 Apple、NVIDIA、Intel、QUALCOMM、AMD 等廠商共同組成了一個新的非營利組織-Khronos Group 以將 OpenCL 發展為一款開放的 API。
後來 OpenCL 1.0 在 2008 年被正式提交到 Khronos Group 並在當年年底通過該組織的審查正式成為了各廠商共同支援的標準,之後 2009 年 Mac OS X Snow Leopard 成為了第一個原生完整支援 OpenCL API 的作業系統,隨後 NVIDIA 與 AMD 也陸續透過驅動程式來在 Windows 下提供對 OpenCL 的支援 (嗯,沒錯,微軟沒有參加,原因等下就會提到了)。
OpenCL 與 CUDA C Code 之間最大的不同點有二,首先是 CUDA C Code 基本上比較著眼於 GPU 運算的部分,在 CPU 與 GPU 同步運用的異質運算 (Heterogeneous Computing) 部分著墨甚少,但 OpenGL 則是從發展之初就很強調異質運算的部分,因此在處理異質運算的部分 OpenCL 的技術會比較成熟,另一個主要不同則是 OpenCL 不論在 NVIDIA、AMD、Intel 內建顯示甚至行動裝置上都能夠使用,是主流通用運算 API 當中唯一可以跨這麼多平台與設備的 API。
至於 AMD 的部分呢,後來 AMD 在 OpenCL 出現之後幾乎就放棄自家的 Brook 了,從 2009 年後的 AMD Stream Technology (後來改名為 AMD-APP) 都以 OpenCL 為主。
至於 CUDA C Code 為什麼沒有隨著 OpenCL 的出現而逐漸凋零,反而演變成 CUDA C Code 這類私有 API 持續與 OpenCL 等通用 API 並存的局面,大概是因為 AMD 在轉用 OpenCL 之前一直沒端出能與 NVIDIA 抗衡的產品,使得有通用運算需求的廠商或人們幾乎都以 NVIDIA 產品為主,累積到 2010 年其實有不少較早導入通用運算技術的廠商或開發者已經用 CUDA C Code 寫好程式了,又加上 NVIDIA 的 GPU 處理 OpenCL 的速度較慢,不及使用 CUDA C Code 的狀況,因此使用 CUDA C Code 的比例一直以來都不低,所以並沒有在 OpenCL 出現之後迅速滅絕,OpenCL 的普及速度也沒有想像中快。
DirectCompute
基本上從參與的廠商名單同時包含了 NVIDIA 與 AMD 兩大廠,甚至還有 Intel 也參了一腳來看就注定了 OpenCL 在未來將會成為通用計算界的主流,在這樣的狀況底下,已經透過 DirectX 與 Direct3D 繪圖 API 主宰 GPU 與遊戲界無數年的微軟當然很不是滋味。
因此微軟成為主要廠商當中唯一缺席 Khronos Group 的廠商,並且自己發展了一套稱之為 DirectCompute 的通用運算 API 與之抗衡 (在 DirectX 11.0 當中首次出現),或許是為了掩飾自家比較晚跟上通用運算熱潮吧?DirectCompute 的第一個版本就直接跳到 5.0 版了 (又或許是對應到 Shader Model 5.0 的意思,因為微軟為此還特別創設了一個稱為 Compute Shader 的名詞),除此之外也將部分特性下放回 DirectX 10 作為 DirectCompute 4.0 (不過由於是用 DirectX 10 的原有功能下去拼湊與模擬,因此在很多部分並不能完整支援)。
這個 API 的後續發展其實蠻有趣的,AMD 與 NVIDIA 或許都基於不敢得罪微軟的立場,或是受到 WHQL 驗證的強制要求,因此在各自推出支援 DirectX 11.0 的 GPU 之後都提供了對 DirectCompute 的支援,並且在許多簡報當中給 DirectCompute 大肆吹捧了一番 (NVIDIA 甚至還說過 DirectCompute 會引領個人電腦通用運算的革命之類的話),不過實際上市占率最高的仍然是 CUDA,而次之的則是 OpenCL,至於 DirectCompute?還看不到車尾燈呢,很有可能是所有通用計算 API 當中支援裝置數最多但使用率最低的一款。
通用計算的現況與未來
從 2006 年開始有 GPGPU 的構想,到 2007 年開始真正有規範出台,2008 年透過新型號的 GPU 正式飛入尋常百姓家,2009 年兩大開放 API 的出現到現在,GPGPU 的發展已經有了將近十年的歷史,在許多影像處理軟體加入對 CUDA 的支援,有些遊戲開始用到 CUDA 與 OpenCL,開始有 TOP500 排行前幾名的超級電腦使用 Intel x86 + NVIDIA CUDA 的異質運算架構,加上 Intel 也開始急著發展 Xeon Phi 之後,通用計算確實成功成為一項重要的技術了沒錯,但也有很多與預期不同的地方。
2016 年的今天,DirectCompute 與 OpenCL 並沒有一如預期的將半私有的 CUDA API 取代 (實際上時至今日你仍然可以看到許多影音編輯、轉檔軟體有著只在使用 NVIDIA GPU 時才會出現的 CUDA 加速選項),DirectCompute 也沒有如同當年 DirectX 逐步打敗 OpenGL 一般的成為主流,反而是 NVIDIA 在通用計算領域不斷坐大,也始終不熱衷於推廣 OpenCL (OpenCL 早在去年就已經發展到 2.1 版了,今年的 GTX 1080 仍然只支援到 2011 年推出的 1.2 版,從 2011 年開始就未有提升),CUDA API 目前似乎也沒有衰敗的跡象,甚至 AMD 在去年還搞了一個 Boltzmann Initiative (其中的 Heterogeneous-compute Interface for Portability,可移植異質運算介面,可以將 CUDA C Code 快速轉換為可以編譯後在 AMD 硬體上執行的 HIP 程式碼),看起來未來很長一段時間會是 CUDA API 與 OpenCL 繼續共同主宰這個市場,至於現任爐主 DirectCompute 是否有望翻身,還得寄望於明年可能推出的 Shader Model 6.0 而定。
比較諷刺的是 OpenCL 在過去幾年內最多的運用並不是用於學術或是遊戲方面的異質運算,反而是在 2011 到 2013 年間使用 GPU 進行 Bitcoin 或 Litecoin 挖礦上,由於先天設計與軟體完善度上的差異導致在 NVIDIA GPU 上使用 CUDA 挖礦的效果與速度並不理想,反而引發 OpenCL 性能較強的 AMD GPU 熱賣,連帶拉高了 OpenCL 的使用率與挽救了當時 AMD GPU 的市占率,不過我還是想說,Bitcoin 這類靠電腦大量運算無意義資料來「產製」貨幣的方式,造就了大量的能量浪費與許多成為電子垃圾的 ASIC 晶片甚至 GPU,這是不是好現象,我個人是存疑的。