CUDA 是由 NVIDIA 推出的平行運算架構,讓 GPU 不只是拿來打電動,而是能處理通用型運算任務(GPGPU)。本文用淺顯易懂的方式,拆解 CUDA 架構與執行流程,從 G80 顯示卡開始,讓你理解 GPU 如何改變平行運算世界。
首先,你不要再看那些根本沒有研究過 GPU 的人在寫 CUDA 的文章了,他們會害死你,他們只是要 CUDA 這個關鍵字的流量,尤其是財金網站上的內容。

為什麼「不是 CPU 來算」?GPU 是怎麼崛起的?
先講結論:GPU 是拿來跑大量「一樣的事情」的怪物。
當 CPU 一次只能專心做幾件事(靠快取與分支預測來彌補),GPU 的策略就是直接開好幾百個小核心,全部丟進去一起算,而這就是平行運算的本質。
但問題來了,早期你想用 GPU 做這件事,要靠 OpenGL、DirectX 這種圖形 API 想辦法繞出來搞 GPGPU。整個開發體驗卡到爆,根本不是為了做通用運算設計的。
NVIDIA 在 2006 推出 G80 晶片時,同時發表了 CUDA 架構,這才真正讓 GPU 平行運算邁進主流。
CUDA 是什麼?不是語言,而是一整套平行運算平台
CUDA 全名是 Compute Unified Device Architecture,是一個讓開發者可以用 C 語言去控制 GPU 執行一般運算任務的開發架構。
簡單說,CUDA 把 GPU「解放出來」,不再只能跑圖形,而是變成一顆平行運算協同處理器(co-processor),由 CPU 控制、GPU 加速。
G80 架構開啟了統一架構(Unified Architecture)
NVIDIA 在於 G80 晶片導入的「統一架構」概念。以前 GPU 是一塊一塊功能分工(Vertex、Pixel)的硬體單元,而 G80 開始,把這些處理器整合成 128 個可程式化的 Stream Processors(SP),每個都是能處理浮點運算的 ALU。
每個 SP 能獨立執行指令,還能關閉做成低階版型號,整塊 G80 晶片有:
- 128 個 SP,分成 8 個 Block,每個 Block 裝 16 顆 SP
- 每個 Block 有自己的 texture unit、filter unit、shared memory
- 支援 348-bit 記憶體頻寬,用 GDDR3 做顯示記憶體
這讓 GPU 不再只是「畫畫(3D圖形)」,而是可以拿來「算數學」。
CUDA 平行運算模型:Thread、Block、Grid 是什麼?
假設今天學校要進行「全校大掃除」,校長(GPU)要分配工作給所有學生(Thread)。但學生太多,直接分配會很亂,所以校長用以下方式組織:
Thread(執行緒)→ 最小工作單位 = 「一個學生」
- 每個學生負責「一個具體任務」,例如:
- 學生A:擦第1扇窗戶
- 學生B:擦第2扇窗戶
- …(每個學生做一件事)
Block(區塊)→ 一組學生 = 「一個班級」
- 一個班級(Block)裡有多個學生(Thread),例如:
- 1年1班(Block 0):學生A、B、C…(共1024人)
- 1年2班(Block 1):學生D、E、F…(共1024人)
- 班級內的特點:
- 學生可以互相幫忙(共享記憶體)。
- 班長可以協調工作(Block內同步)。
- 但不同班級的學生不能直接溝通(Block之間獨立)。
Grid(網格)→ 所有班級 = 「全校」
- 全校(Grid)由所有班級(Block)組成,例如:
- 1年級(Block 0~10)、2年級(Block 11~20)…
- 校長(GPU)的指令:
- 校長廣播:「現在全校擦窗戶!」(一個Kernel指令)。
- 每個班級(Block)收到指令後,分配給自己的學生(Thread)執行。
為什麼要這樣分層?
- 每個 Block 只能容納有限數量 Thread(例如 1024)
- 有了 Grid,就能無限 scale(幾萬、幾十萬筆資料一起處理)
- 每個 Thread / Block 都有自己的 ID,可以定位資料在處理陣列中的位置
而這樣的分層帶來的好處是:
- 效率問題:
- 如果校長直接管1萬個學生(Thread),會累死(管理成本高)。
- 透過班級(Block)分層,校長只需管班長,班長再管學生。
- 資源限制:
- 一個班級(Block)最多只能有1024人(硬體限制)。
- 但全校(Grid)可以有無限多班級,所以能處理超大型任務(例如幾十萬扇窗戶)。
- 分工明確:
- 每個學生(Thread)知道自己負責哪扇窗(透過ID定位)。
- 例如:學生ID=5 → 擦第5扇窗;班級ID=3 → 負責3樓的窗戶。
這種模型讓資料可以被「一份邏輯」但「多個資料」同時處理(SIMD),非常適合影像處理、矩陣運算、模擬等平行性高的任務,例如:
- 影像處理:
- 一張圖片有100萬畫素 → 用100萬個Thread(每個Thread處理1畫素)。
- 這些Thread分到多個Block(例如1024 Threads/Block),最後組成一個Grid。
- 科學計算:
- 矩陣運算時,每個Thread算一個格子,Block和Grid幫你自動分配任務。
CUDA 記憶體模型:不是一堆 RAM,就能跑得快
很多人以為 GPU 快,是記憶體大、頻寬高,但其實 CUDA 架構裡記憶體分成:
| 記憶體類型 | 層級 | 誰可以用 | 特性 |
|---|---|---|---|
| Register | Thread 層 | 單一 Thread 使用 | 最快 |
| Shared Memory | Block 層 | 同一個 Block 的 Threads 可共用 | 快速通訊 |
| Global Memory | Grid 層 | 所有 Block 都能訪問 | 慢但共享 |
| Constant / Texture Memory | Grid 層 | 所有執行緒都能讀,但不能寫 | 適合放「不會變」的資料,快取友善,能加速影像與查表任務 |
這種分層結構,加上記憶體搬運流程(host ↔ device 的 copy),是 CUDA 執行效能最佳化的關鍵,也是為何寫 CUDA 時記憶體配置會佔那麼多功夫。
假設學校合作社(GPU)要讓學生(Thread)快速存取物品(資料),但直接讓所有人搶同一個大櫃子(Global Memory)會很慢,所以設計了多層儲物櫃系統來最佳化效率:
Register(寄存器)→ 學生口袋(最快但最小)
- 特性:
- 每個學生(Thread)有自己的口袋(Register),只能放少量東西(例如一支筆、一張紙)。
- 超快:東西放在身上,隨手就能拿(無需排隊)。
- 限制:
- 口袋空間小,放不下課本(大資料)。
CUDA 用途:暫存計算中的臨時變數(如迴圈計數器)。
Shared Memory(共享記憶體)→ 班級共用櫃(Block 專用)
- 特性:
- 每個班級(Block)有一個共用櫃(Shared Memory),全班同學(Thread)都能存取。
- 速度快:櫃子在教室內(GPU晶片上),不用跑去合作社。
- 適合小組協作:例如全班一起算數學題,中間結果放共用櫃。
- 限制:
- 只有同班同學(同Block的Thread)能用,別班不能偷看。
CUDA 用途:加速Block內Thread的通訊(如矩陣分塊計算)。
Global Memory(全局記憶體)→ 合作社大倉庫(全GPU共用)
- 特性:
- 全校(Grid)共用的大倉庫(Global Memory),所有班級(Block)都能存取。
- 速度慢:要從教室走到合作社(存取延遲高)。
- 容量大:能放課本、掃具等所有東西(大型資料)。
- 關鍵問題:
- 如果全校學生同時去倉庫拿東西,會塞車(頻寬瓶頸)。
CUDA 用途:儲存輸入/輸出資料(如影像、矩陣)。
Constant / Texture Memory(常數/紋理記憶體)→ 公告欄(只讀)
- 特性:
- 像學校的「公告欄」,貼著全校通用的資訊(例如課表、地圖)。
- 只能讀取,不能修改(常數資料)。
- 有快取(Cache):常用資料(如地圖)會複製一份到教室附近,加快讀取。
- 優勢:
- 適合放不變的參考資料(如數學公式)。
CUDA 用途:儲存預設參數(如機器學習的權重)。
為什麼要分這麼多層?
- 速度差異:
- 從「口袋(Register)」拿東西比「跑合作社(Global Memory)」快100倍!
- 如果所有資料都塞進Global Memory,GPU會卡在「等資料」而非「算資料」。
- 協作需求:
- 班級內(Block)要快速共享中間結果(用Shared Memory),避免一直跑倉庫。
- 硬體限制:
- Register和Shared Memory空間少,但速度快,必須手動規劃哪些資料放哪裡。
舉個栗子:處理一張圖片
- Global Memory:原始圖片(大資料,放倉庫)。
- Shared Memory:每個Block載入一小塊圖片(如8×8像素)到教室櫃子,快速處理。
- Register:每個Thread計算像素時,用口袋暫存結果。
- Constant Memory:儲存濾鏡參數(如模糊效果的參數值)。
如果沒分層,所有Thread都去Global Memory搶資料,速度會像「全校擠合作社」一樣崩潰!
CUDA 程式怎麼執行?
基本流程如下:
- 程式寫好後,用 CUDA 編譯器把 GPU 部分編譯成 device code
- CPU 負責初始化、分配記憶體、發動 kernel 呼叫
- GPU 接到 kernel 後,用所有 Multiprocessor(SM)分批執行 block
- 每個 active block 被切成 warps,每個 warp 同時執行(但順序不保證)
- 資料處理完後傳回 host(CPU)
但這段你看不懂對不對?對! 20 年前的我也看不懂,沒關係。

用「學校園遊會分工」比喻 CUDA 執行流程
假設學校要舉辦一場大型園遊會(GPU 計算任務),整個活動的運作流程和 CUDA 程式執行非常相似:
1. 事前準備:寫程式 & 編譯
- 主辦組(CPU):
先規劃好園遊會的所有工作內容(寫好程式碼),並把需要「大量人力並行處理」的工作(如攤位遊戲、餐飲製作)特別標記出來(GPU 代碼)。- 這些標記的工作會交給專業活動公司(CUDA 編譯器)轉換成「園遊會專用指令」(device code)。
2. 活動啟動:CPU 發起任務
- 主辦組(CPU) 負責:
- 租借場地(分配 GPU 記憶體)
- 通知所有工作人員待命(初始化 GPU)
- 大喊:「現在開始執行園遊會!」(發動 Kernel 呼叫)
3. 現場執行:GPU 分工處理
- 活動公司(GPU) 收到指令後:
- 將所有工作分成多個大組(Block),例如:
- 遊戲區(Block 1)
- 餐飲區(Block 2)
- 表演區(Block 3)
- 每組分配給一個專業小隊(Multiprocessor, SM)負責執行。
- 將所有工作分成多個大組(Block),例如:
- 小隊(SM)內部:
- 每個組(Block)再細分成小隊列(Warp,通常是 32 人),例如:
- 遊戲區的「套圈圈小隊」(Warp 1)
- 遊戲區的「投籃小隊」(Warp 2)
- 這些小隊列同時開工,但誰先做完不保證(執行順序不固定)。
- 每個組(Block)再細分成小隊列(Warp,通常是 32 人),例如:
4. 工作完成:回報結果
- 當所有攤位(Block)的工作結束後:
- 活動公司(GPU)把成果(如營業額、照片)整理好,送回主辦組(CPU)。
- 主辦組(CPU)繼續處理後續報表(例如統計總收益)。
白話總結
- 開發者只需寫「每個 Block 要做什麼」,其他分工細節 CUDA 自動搞定。
- CPU 像主辦單位,只負責「發號施令」和「收結果」。
- GPU 像專業活動公司,接到指令後:
- 把大任務拆成 Block(攤位)
- 分給 SM(小隊)
- 小隊內用 Warp(小隊列)快速並行處理
顯示卡不只是跑遊戲,還能進叢集、搞 HPC
綜合以上所說,CUDA 的架構設計,讓 GPU 可以很自然地接入大型平行運算環境,像是 supercomputer、server farm、cluster 等。
每台機器都有自己的顯示卡(作為 co-processor),整體算力是以「node × GPU 數量」來疊加,這讓 GPU 不再是「單機加速器」,而是真正的分散式算力單元。
這也是今天 AI 模型訓練、深度學習架構大量依賴 GPU 的根本原因之一。
常見問題
CUDA 是不是一種程式語言?
不是!CUDA 是 NVIDIA 設計的「工具箱」,裡面包含:
架構設計圖(怎麼讓 GPU 高效工作)
開發工具(編譯器、除錯器)
現成函式庫(像數學公式速查表)
你還是用 C/C++ 寫程式,只是加上一些「特殊標記」告訴 GPU 哪些部分要加速。
CUDA 可以跑在所有顯示卡上嗎?
只有 NVIDIA 顯示卡(型號 GeForce 8 系列之後)才能用。
AMD 或 Intel 的顯示卡要用其他工具(如 OpenCL)。
就好比,CUDA 是「NVIDIA 公司專屬的變壓器」,別家顯示卡插了沒電。
CUDA 和 OpenCL 有什麼不同?
CUDA 像 iPhone:封閉但順暢,專為 NVIDIA 顯卡設計。
OpenCL 像 Android:開放但各家體驗不同。
我不是寫 AI,也要學 CUDA 嗎?
看情況!
需要學的情境:
你的工作有「大量重複計算」(例如:影片轉檔、科學模擬、3D 渲染)。
你想讓程式跑快 10 倍~100 倍(GPU 平行加速)。
不用學的情境:
你寫網頁、手機 App、文書處理(用不到 GPU 加速)。
就好比:
你只是「煮泡麵」(簡單任務),不需要買專業廚房(CUDA)。
你要「開餐廳」(高效能計算),CUDA 就是你的 高效爐具。