第二章練習題 (Practice - Programming GPUs in CUDA)

Question 1 - Kernel 宣告與 launch 基礎 [recall]

在 CUDA C++ 中要用什麼 declaration specifier 與回傳型別定義 kernel?<<<a, b>>> 中 a、b 各代表什麼?每個 block 的 thread 上限是多少?

Question 2 - Unified vs Explicit 記憶體管理 [recall]

比較 cudaMallocManagedcudaMalloc+cudaMemcpy 兩種做法;cudaMemcpy 是同步還是非同步?page-locked host memory 用哪個 API 配置、為何需要?

Question 3 - 計算 grid 大小與邊界檢查 [application]

向量長度 vectorLength = 1000、每 block 256 threads,要啟動幾個 block?kernel 內為何需要 if (workIndex < vectorLength)

Question 4 - launch 後得到 cudaSuccess 的意義 [analysis]

程式在 kernel launch 後立即 cudaGetLastError() 得到 cudaSuccess,能否代表 kernel 已成功執行完畢?要如何抓到 kernel 執行期間(如非法記憶體存取)才發生的非同步錯誤?

Question 5 - numba.cuda kernel 與 launch 語法 [recall]

Python 用什麼裝飾器把函式標成 kernel?何時編譯?launch 語法為何、對應 C++ 什麼?cuda.grid(1) 等於什麼?

Question 6 - 自動邊界檢查與 block_size=2048 [application]

一個 numba.cuda vecadd kernel 直接寫 C[idx] = A[idx] + B[idx] 而沒有越界檢查,且 vector_size 不是 block_size 的倍數,為何安全?若把 block_size 設成 2048 會發生什麼?

Question 7 - Local memory 的 scope 與實體位置陷阱 [recall]

從 scope / lifetime / location 三維度說明 local memory;它與 register 速度一樣嗎?哪些記憶體實體在 SM 上、哪些在 device 上?

Question 8 - __syncthreads() 的語意與限制 [recall]

__syncthreads() 提供什麼保證?同步範圍多大?把它放在只有部分 thread 進入的 divergent 分支會怎樣?

Question 9 - 矩陣轉置為何寫入 c 不合併 [analysis]

global memory 轉置 kernel c[INDX(myCol, myRow, m)] = a[INDX(myRow, myCol, m)](INDX 為 row-major),為何讀 a 合併但寫 c 不合併?何時變成病態案例?怎麼修?

Question 10 - 消除 shared memory bank conflict [application]

宣告 __shared__ float smem[32][32],warp 內 thread 以 smem[threadIdx.x][threadIdx.y]threadIdx.x 為第一索引)存取會有什麼 bank 問題?為什麼?怎麼修正?

Question 11 - Tile kernel 宣告與啟動 [recall]

C++ tile kernel entry point 與 device function 各用什麼修飾符(類比 SIMT 什麼)?triple-chevron 第二參數要填什麼、為什麼?tile 每一維有什麼限制?

Question 12 - Tile 兩種記憶體搬移方式 [recall]

tile 程式有哪兩種把 array 資料搬進/出 tile 的方式?哪一種能下放到 TMA、效能較好?C++ 建 partition view 的兩步驟為何?

Question 13 - Tile atomics 的 thread scope 選擇 [analysis]

tile 上 cross-block contention 與 intra-block contention 各該用什麼 thread scope?C++ 與 Python 的 thread scope 預設值有何關鍵差異?整個 atomic call 是 atomic 的嗎?

Question 14 - Tile broadcasting 形狀與 GEMM K-loop [application]

rank-2 的 8x2 tile 與 rank-3 的 4x1x2 tile 相加(依 NumPy 語義),結果形狀為何?GEMM 慣用什麼精度累加、K-loop 迭代幾次?

Question 15 - Streams、async copy 與 event 計時 [recall]

在哪個 triple-chevron 參數指定 stream?非同步傳輸用哪個 API、host buffer 有什麼要求?用 event 計時的 API 與單位為何?

Question 16 - Default stream 的 blocking 行為與 CUDA Graphs [analysis]

三個 kernel 分別在 stream1、default stream、stream2 啟動(stream 用 cudaStreamCreate 建立),為何它們不會並行?如何避免?反覆執行同一串操作時 CUDA Graphs 如何降低開銷?

Question 17 - UVA 與 managed memory [recall]

UVA 提供什麼?如何由指標判斷記憶體位於 CPU 或哪個 GPU?配置 managed memory 有哪三種方式?在哪種系統上所有 system memory 自動就是 managed memory?

Question 18 - Unified memory paradigm 屬性與 cudaHostRegister 指標陷阱 [recall]

用哪三個 device attribute 判斷 unified memory 型態?用 cudaHostRegistermalloc 配置的記憶體 map 給 GPU 後,kernel 內要用哪個指標?

Question 19 - compute_XY vs sm_XY 與 -arch=native [recall]

-arch=compute_XY-arch=sm_XY 各產生什麼、差別何在?-arch=native 有什麼代價?device code 的編譯鏈順序為何?

Question 20 - Separate compilation 與 LTO [recall]

要讓某 compilation unit 的 device function 呼叫另一單元定義的 device function,需要加什麼 flag?這稱為什麼、為何不是預設?LTO 解決什麼問題、如何啟用?

模式總結