前十天一直盯著 RISC-V CPU、RVV intrinsic、SGLang RVV 後端和 PyTorch Inductor RVV,滿腦子都是 CPU core、vector register、cache 和 C++ kernel,今天終於要換到 GPU 了。
今天先從工作組織、硬體執行與資料存取三個角度拆解 NVIDIA GPU。後面看到 warp、SM、shared memory、Tensor Core、TMA、WGMMA 時,才有辦法把這些硬體名詞接回 compiler lowering 和 runtime launch,不然名詞很多很容易全部混在一起。
我這次會沿著 NVIDIA CUDA Programming Guide 與官方架構資料,以 Hopper、Blackwell 與 Vera Rubin 三代比較。Vera Rubin 部分會再區分 Rubin GPU 與整體平台,最後回到 DGX Spark,我們之後實驗會在上面跑。

這是概念圖,圖中的 core、SM 和快取數量不代表某一款處理器的實際規格。
之前看 CPU 的時候,我的思考方式比較像這樣
少量強核心
-> 每個 core 有複雜控制邏輯、cache hierarchy、branch predictor
-> 用 SIMD 把單一 core 的資料平行度拉高
-> 盡量讓 hot loop 吃滿 vector register 和 cache
CPU 很擅長處理控制流程複雜、分支多、資料相依性強的工作。像 runtime control、operator dispatch、系統呼叫、資料前處理,CPU 的強項是低延遲和彈性。就算資料不完全規則,CPU 也比較能靠 branch predictor、out-of-order execution、cache 做補救。
GPU 的方向不同,GPU 把大量電晶體放在平行運算單元和高頻寬記憶體上,適合處理大量相同形狀的資料工作
大量較小的執行單元
-> 用 warp / thread block 管理平行工作
-> 用 shared memory / register 做 tile 內資料重用
-> 用 HBM、GDDR 或高頻寬統一記憶體供應資料
-> 用 Tensor Core 加速矩陣乘法
所以 CPU 和 GPU 寫 kernel 時,在意的方向不太相同
| 問題 | CPU | GPU |
|---|---|---|
| 平行單位 | thread、core、vector lane | grid、block、warp、thread |
| 資料重用 | L1/L2/L3 cache、vector register | global memory、L2、shared memory、register |
| 算力來源 | scalar pipeline + SIMD | CUDA cores + Tensor Cores |
| 控制流程 | branch 成本較低,硬體有複雜預測 | warp divergence 會讓同一 warp 分批跑 |
| 常見瓶頸 | cache miss、vectorization 不完整、thread overhead | memory coalescing、occupancy、register pressure、shared memory bank conflict |
GPU 這裡有很多名詞容易搞混,讓我們從三個角度拆解 GPU kernel 執行
| 觀察角度 | 要回答的問題 | 主要名詞 |
|---|---|---|
| 工作組織 | 一次 kernel 的工作怎麼切分? | grid、block、warp、thread |
| 硬體執行 | 這些工作被送到哪裡執行? | GPU、SM、warp scheduler、運算單元 |
| 資料存取 | 執行時誰能使用資料,load / store 又走哪條路? | register、shared memory、global memory、L1 / L2、HBM |
如果名詞混在一起,先問它是工作、硬體,還是資料?例如 block 是一組工作,SM 是執行工作的硬體,shared memory 是這組工作在 SM 上使用的共用資料區。
CPU 啟動 kernel
↓
產生一個 grid,grid 裡有很多 blocks
↓
每個 block 被分派到某個 SM
↓
block 裡的 threads 以 warp 為群組執行
↓
SM 的 warp scheduler 選擇 ready warp,發射下一道指令
↓
指令使用 register / shared memory,或經 L1 / L2 存取 global memory
block 被分派到 SM 是三個角度之間重要的接點,下面會沿著這條主線依序展開。
CUDA kernel 啟動時,工作會組織成 grid -> blocks -> threads,NVIDIA GPU 執行時還會把同一 block 內的 threads 組成 warps
| 層級 | 先怎麼理解 | 和硬體執行的關係 |
|---|---|---|
| Grid | 一次 kernel launch 產生的全部工作 | blocks 會分散到多個 SM |
| Block | 一組可以合作與同步的 threads | 一個 block 執行時會駐留在一個 SM |
| Warp | SM 排程與發射指令的基本群組 | NVIDIA warp 由 32 個 threads 組成 |
| Thread | 程式看到的單一執行個體 | 擁有自己的 thread ID 與私有資料 |
例如這個啟動設定
kernel<<<80, 256>>>(...);
它會產生 1 個 grid,其中有 80 個 blocks,每個 block 有 256 個 threads。一個 block 的 256 個 threads 會形成 8 個 warps,因為 256 / 32 = 8。
這 80 個 blocks 不會各自綁定一個專屬 SM,GPU 會把 blocks 分派給當下有資源的 SM,前一批 blocks 完成後,同一批 SM 還可以繼續執行剩下的 blocks。
進入一個 SM 後,warp scheduler 會從已駐留的 warps 中挑選當下可執行的 warp。CUDA 的 SIMT programming model 讓程式看起來像每個 thread 各自執行 scalar code,實際發射指令時則以 warp 為群組。同一 warp 內的 threads 走不同 branch 會產生 divergence,讀取連續 global-memory 位址時,則較容易合併成有效率的記憶體交易。
前一節描述工作如何組織,現在再把它放到實體 GPU 裡
grid → 其中的 blocks 可分散到 GPU 上多個 SM
block → 執行時駐留在一個 SM
warp → 由 SM 內的 warp scheduler 排程
thread → 在 warp 中以一個邏輯執行個體的角度執行程式
一個 thread 不會從 kernel 開始到結束,始終獨佔某一個 CUDA core。
CUDA core、Tensor Core、load/store unit 是執行不同類型指令的硬體單元,warp scheduler 會依指令類型和資源狀態發射工作。
如果把一顆 NVIDIA GPU 從外到內拆開,可以用這張簡化圖對照
Host CPU
|
PCIe / NVLink
|
GPU package
|-- HBM / GDDR memory
|-- Memory controllers
|-- L2 cache
|-- GPC / TPC / SM groups
|-- SM
|-- warp schedulers
|-- dispatch units
|-- register file
|-- shared memory / L1
|-- CUDA cores
|-- Tensor Cores
|-- load/store units
|-- special function units
不同 NVIDIA 世代的實際命名和數量會變,後面會再針對各元件仔細說明。
知道 block 會駐留在一個 SM 後,記憶體名詞就有了參考點:thread 執行指令需要私有資料,同一 block 的 threads 需要一塊合作區域,所有 blocks 還需要存取大容量的輸入與輸出。
因此,CUDA 討論記憶體時,要把資料存取和前兩個角度連起來
thread 私有資料 → register,或 spill 到 local memory
block 合作資料 → 該 block 駐留 SM 內的 shared memory
所有 threads 存取 → global memory,途中可能經過 L1 / L2 快取
這裡又要再分成兩個問題,看到一筆資料時可以問

圖片來源:NVIDIA CUDA C++ Programming Guide, Figure 6: Memory Hierarchy
第一次看可以先記住 thread → register / local、block → shared、grid → global 。
下面是完整版,可以多看幾次不需要一次記住很多細節,這裡名詞太多了。
| 名稱 | 誰看得到 | 生命週期 | 常見實體位置 | kernel 編寫時的重點 |
|---|---|---|---|---|
| Register | 單一 thread | thread 執行期間 | SM register file | 最貼近運算單元;過多會壓低 occupancy |
| Local memory | 單一 thread | thread 執行期間 | device memory,通常經 L1 / L2 快取 | 大型區域陣列、動態索引或 register spill 可能落到這裡 |
| Shared memory | 同一 thread block | block 執行期間 | SM 內的可程式化記憶體 | 適合 tile 重用;要處理同步、容量與 bank conflict |
| Distributed Shared Memory | 同一 thread block cluster | cluster 執行期間 | cluster 內多個 SM 的 shared memory | Hopper 起可讓 cluster 內 block 互相存取 |
| L1 / texture cache | 單一 SM 上的存取 | 由硬體管理 | SM 內,常與 shared memory 共用容量 | 降低重複的 device-memory 存取;不由 thread 直接分配 |
| L2 cache | 全 GPU 的 SM | 由硬體管理 | 全 GPU 共用 | 跨 block、跨 SM 重用;排程順序會影響 hit rate |
| Global memory | 所有 threads | allocation 存在期間 | HBM、GDDR 或整合式 GPU 的 LPDDR | 容量大、頻寬高,延遲也高;需要 coalesced access 與資料重用 |
| Constant / texture memory | 所有 threads,以讀取為主 | allocation 存在期間 | device memory 加上專用快取路徑 | constant 適合 warp 內讀取同一位址;texture 支援特定的空間存取模式 |
GPU 不是單獨存在,程式通常從 CPU 端啟動 kernel,資料也常常要從 host memory 搬到 device memory。桌機或一般伺服器常見是 PCIe,大型 NVIDIA 系統會看到 NVLink / NVSwitch。
這裡影響的是 host-device transfer 成本,如果資料一直在 CPU 和 GPU 之間來回搬,就算 kernel 本身很快,整體時間也會被 transfer 吃掉。
所以 benchmark 需要區分只量 kernel time,還是量 host-to-device + kernel + device-to-host。
記憶體階層我喜歡從容量、延遲與頻寬來觀察
算術密度(arithmetic intensity)是連接運算與記憶體的簡單方法
算術密度 = 運算量 / 從記憶體搬移的資料量
同一個 weight tile 如果只用一次,kernel 很容易被 HBM 頻寬限制,搬到 shared memory 或 register 後重用多次,算術密度才會上升。這也是 prefill 的大型 GEMM 較容易吃滿 Tensor Core,小 batch decode 卻常受 weight 與 KV cache 搬移限制的原因。
資料進到 GPU 後,主要會放在 device global memory。資料中心 GPU 常見 HBM,消費級或部分工作站卡會看到 GDDR。HBM / GDDR 的頻寬很高,但延遲仍然比 register / shared memory 大很多。
所以 GPU kernel 常見策略是
從 global memory 讀一大塊
-> 搬到 shared memory 或 register
-> 在近的地方重用多次
-> 最後再寫回 global memory
之後會談到的 Triton matmul 裡的 BLOCK_SIZE_M/N/K,本質上就是在決定一次搬多少 A/B tile,讓資料在 register / shared memory 裡被重用。
L2 cache 位在 SM 和外部記憶體之間,它不是某個 thread block 私有的,會被多個 SM 共享。
這對 matmul 很重要,假設不同 program instance 會讀到相同的 A tile 或 B tile,program order 會影響 L2 hit。這也是 Triton matmul tutorial 裡 GROUP_SIZE_M 會出現的原因:把相關 output tile 的計算順序排近一點,讓剛讀過的資料比較可能還在 L2 裡。
Streaming Multiprocessor (SM) 是 CUDA kernel 執行時重要的硬體單位。可以先把它想成負責執行 thread block 的工作區,一個 GPU 有很多 SM,kernel launch 後,thread blocks 會被分派到不同 SM 上跑。
一個 SM 裡面通常會有
Hopper H100 的官方 SM 圖可以把上面的清單對回實體區塊

圖片來源:NVIDIA Hopper Architecture In-Depth, Figure 4。圖中一個 SM 分成四個處理分區,每區有 warp scheduler、dispatch unit、register file、運算單元與第四代 Tensor Core;下方是 TMA 與共用的 L1 data cache / shared memory。
這裡直接決定 occupancy,當一個 block 使用太多 register 或 shared memory,同一個 SM 能同時駐留的 block / warp 數量就會下降。反過來,如果 block 太小或 work 太少,也可能吃不滿 SM。
GPU global memory latency 很高,GPU 常用的做法是讓很多 warp 同時駐留在 SM 上,當某個 warp 等 memory,scheduler 可以切到另一個 ready warp 執行。
所以 GPU 最佳化裡常看到 occupancy,它不是越高一定越好,但太低會讓 GPU 沒有足夠 warp 可以切換,memory latency 比較容易暴露出來。
Register 是 thread 私有的高速儲存空間。Triton matmul 裡的 accumulator 通常會放在 register。BLOCK_SIZE_M/N 變大時,accumulator 變大,register 用量也會上升。
register 用太多會讓同一個 SM 能放的 warps 變少。大 tile 可能讓單次 tl.dot 處理更多資料,也可能讓 ptxas 配出更多 register,最後壓低 occupancy。
Shared memory 是同一個 thread block 內 threads 可以共同使用的高速記憶體。它常被用來放 A/B tile、做 data staging、降低 global memory 重複讀取。
對 matmul 來說,常見流程是
global memory 讀 A/B tile
-> 放到 shared memory
-> Tensor Core / CUDA cores 重複使用
-> 沿 K 維度處理下一個 tile
shared memory 也有自己的限制,例如容量、bank conflict、同步成本。Triton 和 CUTLASS 的 pipeline 設計會一直碰到這些問題。
Tensor Core 是 NVIDIA GPU 上專門處理矩陣乘加的硬體。對 AI workload 來說,GEMM、attention、convolution、MLP projection 都會盡量接到 Tensor Core。
在 Triton 裡,tl.dot 是很重要的入口。前端看起來是一個 tile-level dot,後端會依照 GPU 架構和 dtype,把它 lowering 到 MMA、WGMMA 或其他 target-specific path。後面談 NVIDIA TTGIR 時,我們會再把這條路徑拆開。
把上面合起來,可以用一個簡化版 matmul path 來看
CPU launch kernel
↓
thread blocks 分派到 SM
↓
warp scheduler 發射 warps
↓
load/store units 從 global memory / L2 讀 A/B tile
↓
shared memory / registers 暫存資料
↓
Tensor Cores 執行 tl.dot 對應的矩陣乘加
↓
accumulator 留在 registers
↓
結果寫回 global memory
後面讀 TTGIR、PTX 和 ptxas 資源資訊時,很多參數都可以放回這條路徑理解
BLOCK_SIZE_M/N/K:一次處理多大的 tile。num_warps:一個 program instance 用多少 warp 合作。num_stages:資料搬移和計算 pipeline 多深。NVIDIA 用 compute capability 表示 GPU 支援的硬體功能和指令能力,格式是 major.minor。例如 H100 的 compute capability 是 9.0,編譯目標就常寫成 sm_90。
這裡的 SM 有兩種用法,我之前第一次讀不小心搞錯
sm_90、sm_100 這類名稱,表示 CUDA 要產生哪一版實體 GPU ISA。sm_90 不是有 90 個 SM。CUDA 編譯時還會看到 compute_90。它是產生 PTX 時使用的虛擬架構,sm_90 則是 ptxas 產生 cubin 時使用的實體架構。fat binary 可以同時放多個 cubin 和一份 PTX,執行時由 driver 選擇相符版本,或用 PTX JIT 補上未預先編譯的目標。
# 產生 Hopper H100 的 sm_90 cubin
nvcc kernel.cu -arch=sm_90
# 查看機器上的 GPU 型號與 compute capability
nvidia-smi --query-gpu=name,compute_cap --format=csv
我對最近三代的 GPU 比較有興趣,先來看資料中心等級 GPU 官方公開的效能規格
| 世代 | 代表硬體 | Compute capability / 編譯目標 | 代表性 GPU 記憶體 | GPU 記憶體頻寬 | 單 GPU NVLink 雙向 scale-up 頻寬 |
|---|---|---|---|---|---|
| Hopper | H100、H200 | 9.0 / sm_90;架構特定功能常用 sm_90a |
H100 SXM:80 GB HBM3;H200:141 GB HBM3e | H100 SXM:3.35 TB/s;H200:4.8 TB/s | NVLink 4:900 GB/s |
| Blackwell | B100、B200、GB200 | B200 為 10.0 / sm_100 |
B200:180 GB HBM3e | 最高 8 TB/s | NVLink 5:1.8 TB/s |
| Rubin(Vera Rubin 平台) | Rubin GPU、Vera Rubin NVL72 | 10.7 / sm_107(CUDA 13.4 Developer Preview) |
最高 288 GB HBM4 | 最高 22 TB/s | NVLink 6:3.6 TB/s |
| 世代 | Tensor Core / Transformer Engine | 矩陣指令與 accumulator | 資料搬移 | 服務工作負載的意義 |
|---|---|---|---|---|
| Hopper | 第四代 Tensor Core、第一代 Transformer Engine、FP8 | wgmma.mma_async;128 threads 的 warp group 合作,accumulator 在 registers |
加入 TMA、transaction barrier、Thread Block Cluster | FP8 降低 weight / activation 流量;H200 的較大 HBM 可容納更多 weight 與 KV cache |
| Blackwell | 第五代 Tensor Core、第二代 Transformer Engine、NVFP4 / microscaling | tcgen05;新增 Tensor Memory(TMEM)保留 accumulator,並支援 CTA-pair MMA |
沿用非同步 pipeline,搭配 TMEM 和新的 MMA 排程 | FP4 再壓低 weight 容量與頻寬壓力;更大 L2、HBM 與 NVLink 有利大模型及 MoE |
| Rubin | 896 個 Tensor Cores、第三代 Transformer Engine、NVFP4 與 3-bit LUT weight 格式 | 每 clock 可處理更大 K 維度;降低高 tensor parallelism 下的 K-loop 次數 | 加強版 TMA、inline descriptor update、更細粒度的 dependent-kernel triggering | 288 GB HBM4 與 22 TB/s 直接對應長上下文、大量 KV cache、MoE 與多 GPU agentic inference |
GPU 記憶體容量和頻寬會依 SKU 與封裝而變,表格不能代替實際部署型號的資料表。NVLink 數字也是 GPU 到 scale-up fabric 的雙向峰值,不等於任意 collective 都會達到這個吞吐量。
Compute capability 主要是指令與硬體功能,實際產品規格則回答 SM 數量、register、shared memory、L2、記憶體容量與頻寬。
Rubin 的 sm_107 來自預覽版工具鏈文件,CUDA 13.4 Developer Preview 也是預先發行軟體,發布效能當作是參考。
H100 / H200 對應 Hopper sm_90。以 H100 SXM 為例,它有 132 個 SM、每個 SM 128 個 FP32 CUDA cores 和 4 個第四代 Tensor Core,另有 50 MB L2、每個 SM 最高 228 KB shared memory,以及約 3 TB/s 的 HBM3 頻寬。H100 PCIe 啟用的 SM 較少,記憶體也改為 HBM2e,H200 沿用 Hopper SM90,主要把記憶體升級為更大容量與更高頻寬的 HBM3e。

圖片來源:NVIDIA Hopper Architecture In-Depth, Figure 3。這是完整 GH100 設計的全晶片圖,共有 8 個 GPC、72 個 TPC 與 144 個 SM;實際 H100 SXM5 啟用 132 個 SM,H100 PCIe 啟用 114 個 SM。
閱讀這張圖時可以從外往內看,晶片邊緣是 HBM controller、NVLink 與 PCIe 介面,中央藍色區塊是分區的 L2 cache,大量重複的綠色區塊則是組成 GPC / TPC 的 SM。資料從 HBM 進入 GPU 後,會經 L2 抵達 SM,再由前面的 SM 內部圖繼續拆成 shared memory、register、CUDA Core 與 Tensor Core。
第四代 Tensor Core 加入 FP8,Transformer Engine 會在 FP8 與較高精度格式之間管理 scaling。對 LLM 訓練與推論來說,Hopper 的硬體主線可以看成兩部分,TMA 負責更有效率地餵資料,WGMMA 負責更大粒度的矩陣乘加。
H100 和 H200 它們都是 Hopper SM90,H200 的主要改變是把 HBM 從 H100 SXM 的 80 GB HBM3、3.35 TB/s,提高到 141 GB HBM3e、4.8 TB/s。同一代指令架構下,只改記憶體容量和頻寬,就可能改變模型能否單卡放入、KV cache 上限與 memory-bound kernel 的吞吐量。
Tensor Memory Accelerator (TMA) 是 Hopper 的非同步資料搬移單元。程式先建立 tensor map,描述 global memory tensor 的 shape、stride、tile 與 swizzle,再由少數 thread 發起一維到五維的 transfer。TMA 可以做 global memory 與 shared memory 之間的搬移,也能配合 multicast 把資料送到 Thread Block Cluster 中多個 block 的 shared memory。
TMA 的關鍵是讓專用單元處理多維位址與大塊 transfer,其他 threads 可以繼續計算。搬移完成後,TMA 會透過 asynchronous transaction barrier 通知 consumer,所以 pipeline 必須一起安排 barrier、producer 與 consumer。
Hopper 也加入 Thread Block Cluster。cluster 內的 blocks 可以保證同時排程,並透過 Distributed Shared Memory 存取彼此的 shared memory。這讓 TMA multicast 和跨 block 合作成為可用的 kernel 設計選項。
WGMMA 的 PTX 指令是 wgmma.mma_async。一個 warp group 由 4 個連續 warp 組成,也就是 128 個 threads。它比傳統 warp-level mma.sync 使用更大的合作範圍,矩陣 operand 會依指令形式來自 registers 或 shared memory,accumulator 則分散在 warp group 的 registers。
名稱裡的 async 也會反映在同步規則。程式要用 wgmma.fence、wgmma.commit_group、wgmma.wait_group 管理非同步 MMA group;shared memory layout、swizzle 和 matrix descriptor 如果不符合指令要求,WGMMA 就不能正確取資料。
這裡還要分清楚 sm_90 和 sm_90a。H100 / H200 的 compute capability 都是 9.0;使用 WGMMA 等 architecture-accelerated features 的 CUTLASS Hopper kernel,需要用 90a target 才能啟用這些功能。一般 SM90 baseline code 仍可使用 sm_90。a 代表程式使用特定架構才有的功能,沒有一般 PTX 的跨世代 forward compatibility 保證。
一個典型 Hopper matmul pipeline 可以簡化成
producer warp:用 TMA 把下一個 A/B tile 搬進 shared memory
↓ transaction barrier
consumer warp group:用 WGMMA 計算目前 tile
↓ commit / wait group
accumulator:留在 registers,最後做 epilogue 並寫回
對 Triton / CUTLASS 這類 compiler 或 template library 來說,Hopper 的重點是
所以後面講 TTGIR Nvidia 時,不能只停在把 tl.dot 變成 MMA,不同 NVIDIA 架構上的 lowering 會受 Tensor Core 指令形狀和資料搬移能力影響。
tcgen05 和 Tensor Memory這裡把 Blackwell 聚焦在 B100、B200 與 GB200 這條資料中心路線,Blackwell 由兩個 reticle-limited dies 組成,中間用 10 TB/s NV-HBI 連接,但 CUDA 程式仍把它視為一個 GPU。B200 對應 compute capability 10.0 / sm_100,支援最高 228 KB shared memory per SM 與第五代 NVLink。B200 有 180 GB HBM3e 與最高 8 TB/s 頻寬,GB200 的 L2 容量則增加到 126 MB。
NVIDIA 官方公開的 Blackwell Ultra SM 圖很適合用來找 TMEM 的位置

圖片來源:NVIDIA Blackwell Ultra Architecture, Figure 2。這是 Blackwell Ultra 的 SM 圖,用來說明 Blackwell 世代的 TMEM、第五代 Tensor Core 與 SM 內部關係;圖中數量不應直接套到 B200 SKU。
SM100 的 Tensor Core 指令族稱為 tcgen05,它也引入幾個會改變 kernel 設計的概念
TMEM 需要單獨說明,它不是一塊可以用一般 load / store 隨意操作的 shared memory,也不是 L1 / L2 快取。Blackwell 的 tcgen05 指令會把矩陣乘加結果寫入 TMEM,後續指令再將結果取出做 epilogue。這是大型 accumulator 不必全部長時間佔用一般 register file。
HBM / L2
↓
shared memory 中的 A/B tiles
↓ tcgen05 MMA
Tensor Memory 中的 accumulator
↓ epilogue 需要時讀出
registers
↓
global memory output
對 compiler 來說,這多了 TMEM 的取得、使用和釋放,也多了 tcgen05 的 commit / wait 和 CTA 合作規則。如果只把 Hopper WGMMA 指令名稱替換掉,沒有重新設計 accumulator 和 pipeline,就還沒有用到 Blackwell 的主要變化。
從 Hopper 到 Blackwell,變化不只是 Tensor Core 峰值提高。Accumulator 的放置、MMA 指令形式、資料精度與跨 GPU 連線都改變了,因此 Hopper 的 WGMMA kernel 不會自動變成最適合 Blackwell 的 kernel。
這裡先分清名稱:Rubin 是 GPU 架構,Vera 是 CPU,Vera Rubin 是把兩者與 NVLink 6、ConnectX-9、BlueField-4 等元件整合在一起的平台。Vera Rubin NVL72 則是包含 72 顆 Rubin GPU 與 36 顆 Vera CPU 的機架級系統。
一般 LLM 推論可以簡化成 CPU 準備請求,GPU 連續產生 token。Agentic AI 的一次請求會在 GPU model call 之間插入許多 CPU 與 I/O 工作:
GPU:模型推論,決定下一個動作
↓
CPU:解析輸出、更新 agent 狀態、執行排程與安全檢查
↓
CPU / I/O:呼叫工具、查詢資料庫、檢索文件、執行 Python 或 shell sandbox
↓
CPU:整理工具結果、序列化資料、組合下一段 prompt
↓
GPU:帶著新 context 繼續推論
強化學習的 rollout 也有相似情況。GPU 產生 action 之後,大量 CPU 環境要執行 action、計算 reward、跑測試或模擬器,再把結果送回下一輪訓練。只要其中一批環境太慢,GPU 就可能等資料,或訓練迭代必須排除來不及完成的樣本。
這類工作有幾個共同特徵,單一 agent loop 內有序列相依性,Python、JavaScript、資料庫與作業系統呼叫帶來大量分支,pointer-heavy 資料結構和不規則存取不容易轉成 GPU 大型矩陣運算;同一台機器還要同時處理成百上千個 sandbox、工具呼叫和 agent 狀態,CPU 需要兼顧單一工作的完成時間,以及滿載時大量平行工作的尾端延遲。
因此,針對 agentic AI 的 CPU可以拆成四個具體問題:
Vera 的設計正好沿著這四個問題展開。
Vera 是 NVIDIA 自行設計 CPU 核心的資料中心處理器,一顆 CPU 有 88 個 Armv9.2 相容的 Olympus 核心。每個核心可透過 NVIDIA Spatial Multithreading 執行兩個硬體執行緒,整顆 CPU 合計 176 個硬體執行緒。
| Vera CPU 設計 | 官方公開規格 | 對 agentic AI 工作負載的對應 |
|---|---|---|
| Olympus 核心 | 88 核心、176 個 Spatial Multithreading 執行緒;每核心 2 MB L2 | 高單執行緒效能縮短工具呼叫、腳本、編譯、reward 與模擬器的序列路徑;雙硬體執行緒提高 sandbox 密度 |
| 寬且深的亂序執行 | 10-wide decode、deep out-of-order engine | 在長相依鏈與不規則程式碼中尋找可先執行的指令,減少單一延遲事件讓整條 pipeline 停住的時間 |
| 分支預測與預先擷取 | neural branch predictor、graph prefetcher | 對應 Python runtime、agent 狀態機、圖形資料與 pointer chasing 中常見的分支和間接記憶體存取 |
| SIMD | 每核心 6 組 128-bit SVE2,支援 FP8 | 處理資料轉換、分析與可向量化的 CPU 工作;agent loop 本身仍有大量 scalar 與控制流程 |
| 統一 L3 與 SCF | 164 MB 統一 L3;第二代 Scalable Coherency Fabric,最高 3.4 TB/s 晶片內雙向剖分頻寬 | 讓 88 核心在滿載時存取共用狀態、記憶體控制器與 I/O,降低跨核心資料交換的延遲變異 |
| 記憶體 | 每個 socket 最高 1.5 TB SOCAMM2 LPDDR5X、最高 1.2 TB/s | 支撐大量平行 sandbox、檢索結果、agent 狀態、資料處理與 KV-cache offload,避免核心密度增加後先卡在 DRAM |
| CPU–GPU 連線 | 第二代 NVLink-C2C,最高 1.8 TB/s coherent bandwidth | 加速 CPU 與 Rubin GPU 共享資料、搬移 agent 狀態與刪除 KV cache,減少 CPU 工作完成後 GPU 等待資料的時間 |
| 系統 I/O | PCIe Gen 6、CXL 3.1;支援 Confidential Computing | 連接網路、儲存與 DPU,並隔離多租戶 sandbox 中的資料和程式碼 |
Olympus 把單一執行緒效能放在很前面,原因來自 agent loop 的序列相依性。模型要先提出工具參數,CPU 才能執行工具,工具結果回來後,runtime 才能組下一個 prompt。這段 critical path 不能單靠增加更多核心縮短。NVIDIA 公開的微架構資料包含 10-wide decode、neural branch predictor、較深的亂序執行,以及處理間接存取的 graph prefetcher,目標都是讓分支多、存取不規則的程式維持較高 IPC。
Spatial Multithreading 則處理另一面,一座 AI 工廠會同時跑大量 agent 和強化學習環境。每個 Olympus 核心可以在需要最低延遲時把較多資源留給單一硬體執行緒,也能將核心資源分給兩個硬體執行緒,提高滿載時的環境密度。
88 個快速核心如果共用一般伺服器 DRAM 頻寬,大量 sandbox 同時掃描狀態、解壓縮資料、跑資料庫或整理檢索結果時,很容易讓核心等記憶體。Vera 使用 SOCAMM2 LPDDR5X,每個 socket 提供最高 1.5 TB 容量和 1.2 TB/s 頻寬。LPDDR5X 在這裡服務的是資料中心 CPU,SOCAMM2 採模組化設計,讓記憶體仍可維修與更換。
第二代 NVIDIA Scalable Coherency Fabric(SCF)把 88 個核心、164 MB 統一 L3、記憶體控制器、I/O 與 NVLink-C2C 接在單一 compute die 上。NVIDIA 公開的最高雙向剖分頻寬為 3.4 TB/s。單一 compute die 可避免核心與共用資料跨越多個 CPU compute chiplet 時產生的額外 hop,對 agent 服務來說,設計目標是讓滿載時的 core-to-core 與 core-to-memory 延遲比較一致。
在 Vera Rubin 系統裡,Vera CPU 與 Rubin GPU 透過第二代 NVLink-C2C 連接,提供最高 1.8 TB/s 的 cache-coherent CPU–GPU 頻寬。它的工作是把前面那段 agent loop 接起來:GPU 做模型推論,CPU 執行工具與 orchestration,接著把結果交回 GPU。
Coherent link 也讓 KV cache offload、共享資料結構與 CPU–GPU pipeline 有更大的設計空間。舉例來說,agent 等待較慢的工具回傳時,系統可能把暫時不用的 KV cache 從 GPU HBM 移出;工具完成後若要還原該對話,CPU–GPU 連線與記憶體管理會影響還原成本。這不是 NVLink-C2C 自動解決的問題,runtime 仍要決定哪些資料保留、刪除和預先搬回。
Vera 的硬體選擇可以整理成一條因果鏈
agent / RL 加入大量 CPU critical path
↓
Olympus 提高分支多、序列性工作的單執行緒進度
↓
Spatial Multithreading 提高大量 sandbox 的平行密度
↓
SCF + 164 MB L3 + 1.2 TB/s LPDDR5X 避免滿載時只增加等待記憶體的核心
↓
NVLink-C2C 將 CPU 工具工作與 Rubin GPU 模型運算接回同一條 pipeline
NVIDIA 2026 年 7 月公開的 Rubin GPU 資料列出
Rubin GPU:224 SM、896 Tensor Cores
記憶體:最高 288 GB HBM4
記憶體頻寬:最高 22 TB/s
Transformer Engine:第三代
NVLink 6:每顆 GPU 最高 3.6 TB/s 雙向 scale-up 頻寬

圖片來源:NVIDIA Rubin GPU Architecture, Figure 2。這是全 GPU 層級的圖,可看到兩個 compute dies、GPC、中央 L2、HBM controller、NV-HBI、NVLink 6 與 PCIe Gen 6;它不是單一 SM 的內部圖。
從圖中可以讀到 Rubin 的設計方向:運算單元增加後,HBM controller、L2、die-to-die link、CPU-GPU 與 GPU-GPU 連線也一起擴充。否則 224 個 SM 與 896 個 Tensor Cores 只會更快地等待資料。
這一代的 kernel 重點開始明確對準 MoE、長上下文 attention 與多 GPU agentic inference
這個系列後續的 Triton 實驗,都會以 NVIDIA DGX Spark 為主要平台。
DGX Spark 是採用 GB10 Grace Blackwell Superchip 的完整桌上型系統。GB10 把 20 核心 Arm CPU、Blackwell GPU、記憶體控制器與其他 I/O 整合在同一個 SoC,和常見的 x86_64 主機加 PCIe 獨立顯示卡有明顯差異。

圖是依照 NVIDIA DGX Spark Hardware Overview 與 DGX Spark Porting Guide:System Architecture 重新畫的。綠色大框是 GB10 SoC,內部整合 20 核心 Arm CPU 與 Blackwell GPU;兩者透過統一記憶體控制器共用 128 GB LPDDR5x。
| 元件 | DGX Spark 官方規格 | 對後續實驗的影響 |
|---|---|---|
| SoC | GB10 Grace Blackwell Superchip | CPU 與 GPU 整合在同一個封裝與記憶體系統中 |
| CPU | 20 核心 Armv9.2:10 個 Cortex-X925 + 10 個 Cortex-A725 | 使用 aarch64 / Arm64 軟體套件;不能直接沿用只提供 x86_64 binary 的 wheel 或容器映像檔 |
| CPU 快取 | 每個 X925 有 2 MB L2、每個 A725 有 512 KB L2;兩個 cluster 分別有 16 MB 與 8 MB L3 | CPU benchmark 要區分核心類型、執行緒綁定與排程結果 |
| GPU | Blackwell GPU、6,144 個 CUDA cores、第五代 Tensor Cores、第四代 RT Cores | 支援 Blackwell 的低精度運算,但不能把 B200 的 SM 數量、HBM 或峰值直接套過來 |
| CUDA 架構 | Compute capability 12.1,實體編譯目標 sm_121 |
native extension、Triton、CUTLASS 與自製 CUDA kernel 都要確認 SM121 支援狀態 |
| AI 峰值 | 最高 1,000 TOPS,或在 FP4 與稀疏性條件下最高 1 PFLOP | 這是特定精度與稀疏條件的理論峰值,不能拿來預測 FP16、BF16 或端到端 token throughput |
| 系統記憶體 | 128 GB LPDDR5x UMA、256-bit、273 GB/s | CPU、GPU、作業系統、page cache 與顯示輸出共同競爭容量和頻寬 |
| 資料搬移 | 2 個 copy engines | 可讓不同方向的資料搬移重疊;實際重疊仍取決於 allocation、stream 與工作負載 |
| 儲存裝置 | 1 TB 或 4 TB 自我加密 NVMe M.2 SSD | 模型權重、容器映像檔與 benchmark dataset 會共用本機空間;每次實驗要記錄實際機型容量 |
| 網路 | 10 GbE、Wi-Fi 7、ConnectX-7;後方有 2 個 QSFP 埠,每埠最高 200 Gb/s | 單機結果不受網路影響;多機 NCCL 實驗要另外記錄拓樸、纜線、介面與通訊版本 |
| 影音 | 1 個 NVENC、1 個 NVDEC、HDMI 2.1a | 影像/視訊工作負載可使用獨立編解碼單元;接螢幕時也會保留一部分系統記憶體 |
| 電力 | 240 W 外接電源供應器;GB10 SoC TDP 140 W | 長時間 benchmark 需要觀察溫度、時脈與功率;使用較低瓦數電源會影響效能或穩定性 |
不需要對 1 PFLOP 有太高的期待,理想很豐滿、現實很骨感,它描述的是 FP4 而且包含稀疏性條件的峰值,後續若量 BF16 GEMM、FP16 attention 或 LLM decode,資料格式、Tensor Core 路徑、記憶體頻寬與 batch shape 都不同。
這張架構圖最值得注意的是 CPU 和 GPU 沒有各自獨立的 DRAM 。DGX Spark 採用動態統一記憶體架構(Unified Memory Architecture, UMA),CPU、整合式 GPU 和作業系統共用同一組 128 GB LPDDR5x,沒有預先切一塊固定容量給 GPU。
在 x86_64 主機加獨立 GPU 的系統上,常見資料路徑是
CPU DRAM 中的 tensor
↓ cudaMemcpy,通常經 PCIe
GPU HBM / GDDR 中的另一份 tensor
↓
GPU kernel
DGX Spark 的實體記憶體路徑則較接近
128 GB LPDDR5x 實體記憶體
├─ Arm CPU 存取
├─ Blackwell GPU 存取
├─ 作業系統與 page cache 使用
└─ 顯示與其他裝置使用
CPU 與 GPU 共用實體 DRAM,可減少 CPU RAM 與 GPU VRAM 各留一份資料的需求。不過,UMA 不等於每一種 CUDA 配置都自動是零複製,也不等於 CPU 和 GPU 同時存取同一筆資料沒有同步成本。程式仍要看自己使用 cudaMalloc、cudaMallocManaged、pageable host memory、pinned memory 或其他配置方式,並遵守 CUDA 的可見性與同步規則。
128 GB 也不是應用程式可以獨佔的 128 GB GPU VRAM。Linux 核心、桌面環境、其他行程、檔案 page cache 與顯示保留區都會占用它。NVIDIA 目前的 DGX Spark 軟體可在 UEFI 中把顯示保留記憶體設為 2 GB 或 4 GB;這項設定和背景行程都可能改變同一個模型在不同時間能否成功載入。
在 UMA 系統上,nvidia-smi 不會像獨立 GPU 一樣提供可直接比較的 Memory-Usage,cudaMemGetInfo 也不會把作業系統可回收的 page cache 與 swap 全部算進可分配容量。
DGX Spark、B200 與 GB200 都使用 Blackwell 世代技術,產品的記憶體與系統目標差很多。
| 比較項目 | DGX Spark GB10 | B200 / GB200 資料中心系統 |
|---|---|---|
| CPU-GPU 關係 | Arm CPU 與 GPU 整合在 GB10 SoC | GPU 搭配主機 CPU,GB200 Superchip 則由 Grace CPU 與兩顆 Blackwell GPU 組成 |
| 記憶體 | 128 GB LPDDR5x UMA,CPU 與 GPU 共用 | B200 使用 180 GB HBM3e GPU 記憶體 |
| 記憶體頻寬 | 273 GB/s,還要和 CPU 與系統共用 | B200 最高 8 TB/s HBM3e |
| CUDA 目標 | sm_121 |
B200 為 sm_100 |
| 電力與散熱 | 140 W SoC、桌上型機身 | 資料中心伺服器的高功率 GPU 與機架散熱 |
| 適合回答的問題 | 軟體移植、功能驗證、單機推論、有限規模微調、kernel 開發 | 大型訓練、高吞吐推論、多 GPU scale-up |
這個比較會直接影響實驗結論。GB10 可以驗證 Blackwell / SM121 上的 CUDA 程式是否正確、Triton 或 CUTLASS 是否產生原生 kernel,也適合研究低功耗桌上型系統的推論行為。GB10 的 273 GB/s LPDDR5x 無法代表 B200 的 HBM3e,還有在 DGX Spark 上觀察到 memory-bound,也不能直接推論同一個 kernel 在 B200 上有相同比例的瓶頸。
今天分享很多 GPU 相關知識
compute_xy 是 PTX 虛擬架構,sm_xy 是 cubin 的實體 ISA 目標,兩者不要和 GPU 裡的 SM 數量混在一起。tcgen05、Tensor Memory、NVFP4 與第五代 NVLink 改變了 accumulator、MMA 與系統連線的設計。明天會分享一下 CUDA、CUTLASS、cuBLAS。今天看硬體,明天看 kernel 和呼叫 library 的部分。
NVIDIA CUDA Programming Guide
https://docs.nvidia.com/cuda/cuda-programming-guide/index.html
NVIDIA CUDA GPU Compute Capability
https://developer.nvidia.com/cuda/gpus
NVIDIA CUDA Compiler Driver:GPU Compilation
https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-compilation
NVIDIA CUDA Best Practices Guide
https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html
NVIDIA Hopper Architecture In-Depth
https://developer.nvidia.com/blog/nvidia-hopper-architecture-in-depth/
NVIDIA H100 Product Specifications
https://www.nvidia.com/en-us/data-center/h100/
NVIDIA H200 Product Specifications
https://www.nvidia.com/en-us/data-center/h200/
NVIDIA Hopper Tuning Guide
https://docs.nvidia.com/cuda/hopper-tuning-guide/index.html
NVIDIA PTX ISA:Asynchronous Warpgroup Level MMA
https://docs.nvidia.com/cuda/parallel-thread-execution/#asynchronous-warpgroup-level-multiply-and-accumulate-operation-using-wgmma-mma-async-instruction
NVIDIA CUTLASS:Warpgroup MMA Programming Guide
https://docs.nvidia.com/cutlass/latest/media/docs/pythonDSL/mma_docs/wgmma_programming.html
NVIDIA Blackwell Architecture
https://www.nvidia.com/en-us/data-center/technologies/blackwell-architecture/
NVIDIA Blackwell Ultra Architecture In-Depth
https://developer.nvidia.com/blog/inside-nvidia-blackwell-ultra-the-chip-powering-the-ai-factory-era/
NVIDIA Blackwell Tuning Guide
https://docs.nvidia.com/cuda/blackwell-tuning-guide/
NVIDIA CUTLASS:tcgen05 MMA Programming Guide
https://docs.nvidia.com/cutlass/latest/media/docs/pythonDSL/mma_docs/tcgen05_programming.html
NVIDIA Rubin GPU Architecture
https://developer.nvidia.com/blog/inside-nvidia-rubin-gpu-architecture-powering-the-era-of-agentic-ai/
NVIDIA Vera Rubin Platform
https://nvidianews.nvidia.com/news/nvidia-vera-rubin-platform
NVIDIA Vera CPU
https://www.nvidia.com/en-gb/data-center/vera-cpu/
NVIDIA Vera CPU:Agentic Workloads in AI Factories
https://developer.nvidia.com/blog/nvidia-vera-cpu-sets-a-new-standard-for-agentic-workloads-in-ai-factories/
NVIDIA CUDA 13.4 Developer Preview Release Notes
https://docs.nvidia.com/cuda/developer-preview/13.4/cuda-toolkit-release-notes/index.html
NVIDIA CUDA 13.4 NVCC:GPU Feature List
https://docs.nvidia.com/cuda/developer-preview/13.4/cuda-compiler-driver-nvcc/index.html#gpu-feature-list
NVIDIA DGX Spark Hardware Overview
https://docs.nvidia.com/dgx/dgx-spark/hardware.html
NVIDIA DGX Spark Porting Guide:System Overview
https://docs.nvidia.com/dgx/dgx-spark-porting-guide/overview.html