第五章練習題 (Practice - Technical Appendices)

Question 1 - Compute Capability 的特性分層與不變上限 [recall]

CC 的三層特性集(baseline / architecture-specific / family-specific)各自的相容承諾與含括關係為何?compute_100compute_100fcompute_100a 三個 target 各能在哪些 device 上執行?哪些技術上限跨所有 CC 不變?


Question 2 - CUDA_VISIBLE_DEVICES 的截斷與 ordinal [application]

在一台四 GPU 機器上設 CUDA_VISIBLE_DEVICES=2,1,-1,3,程式裡 cudaGetDeviceCount() 回傳多少?cudaSetDevice(0) 會選到哪顆實體 GPU?若改設為空字串又如何?


Question 3 - JIT 快取、Module Loading 與 Override 規則 [recall]

CUDA_LAUNCH_BLOCKING=1 的用途與代價是什麼?CUDA_MODULE_LOADING 的預設值與 LAZY/EAGER 差異?CUDA_FORCE_PTX_JITCUDA_FORCE_JITCUDA_DISABLE_PTX_JITCUDA_DISABLE_JIT 的覆蓋關係為何?


Question 4 - C++ 標準在 Device Code 的支援與限制 [recall]

nvcc 用哪個旗標選 C++ 標準、傳入後做什麼?C++11 在 device code 不支援哪「一整組」特性?C++20 又缺席哪兩大功能?libcu++ 是什麼、解決什麼問題?


Question 5 - device printf 與 device malloc heap [recall]

device printf() 的回傳值與標準 C 有何不同、引數上限多少?它的 host-side buffer 預設多大、什麼性質、程式結束會不會自動 flush?device 端 malloc() 從哪配置、預設 heap 多大、配置出的記憶體能否用 cudaFree 釋放?


Question 6 - Lambda 執行空間、Extended Lambda 與 nvstd::function [recall]

lambda 的執行空間如何決定?哪種 lambda 才能當 __global__ 引數?什麼是 extended lambda、它的捕捉有哪些限制、*this 捕捉解決什麼問題?nvstd::function 能否跨 host/device 邊界傳遞?


Question 7 - 通用語言限制與 host→device 傳參的兩個陷阱 [analysis]

device code 不支援哪些 ISO C++ 功能(至少四項)?__global__ 參數總大小上限、經哪段記憶體傳遞?當從 host 啟動 kernel、參數是帶 user-defined copy constructor 與 non-trivial destructor 的 class 時,CUDA Runtime 的處理會「偏離標準 C++」造成哪兩個陷阱?


Question 8 - __launch_bounds__ / __maxnreg__ / __grid_constant__ [application]

你的 kernel 啟動時報「too many resources requested for launch」,__launch_bounds__ 如何幫忙、它的第一個參數對應哪個 PTX directive?__launch_bounds____maxnreg__ 能否同時用?想讓 grid 內所有 thread 共用一份唯讀參數位址、省去 per-thread copy,該用什麼?


Question 9 - 同步原語與 Memory Fence 的三層 Scope [recall]

__syncthreads() 等待的對象是什麼、放在條件式中需要什麼前提?三層 memory fence(__threadfence_block/__threadfence/__threadfence_system)各對哪些觀察者生效?fence 能不能保證寫入「可見」?


Question 10 - Atomic 五種提供方式、五級 Scope 與 atomicCAS [analysis]

CUDA 提供哪五種 atomic、哪種推薦?Legacy atomic 的記憶體序與 scope 後綴慣例為何?Built-in __nv_atomic_* 的 thread scope 有哪五級、對 order/scope 引數有何硬性要求?用 atomicCAS 自製浮點 atomicAdd 時,為何「必須用整數位元樣式比較」?


Question 11 - Warp 函式為何 Volta+ 必帶 mask 與 __CUDA_ARCH__ [recall]

所有 warp *_sync intrinsic(__shfl_sync/__ballot_sync/__reduce_*_sync 等)為何在 Volta 之後必須帶 mask?mask 的「呼叫/非呼叫 thread」bit 規則是什麼、不同 mask 何時可並發?warp *_sync 提供 memory ordering 嗎?__CUDA_ARCH__ 在哪裡有定義、-arch=compute_80,code=sm_90 時其值為何?


Question 12 - 編譯器提示與 Warp Matrix (WMMA) [recall]

#pragma unroll 無引數、1-1 三種情況各做什麼?__builtin_assume(pred) 在執行期為 false 時的後果?WMMA 需要的最低 compute capability、mptr 的對齊要求、mma_syncsatf=true 時對 NaN 的處理各為何?為何不可直接互傳 fragment?


Question 13 - IEEE-754 符合度、FMA 與 Denormal [recall]

CUDA 遵循哪版 IEEE-754、有哪三項主要限制?FMA(a*b+c)為什麼比分開的乘加更精確?denormal 是什麼、用哪個旗標關閉、它被包在哪個總開關裡?global 與 shared memory 上的 atomic single-precision add 對 denormal 的處理有何差別?


Question 14 - 標準數學函式 vs Intrinsic 的精度取捨 [application]

你的 kernel 想加速三角/除法運算,正在標準庫函式(cuda::std::/Math API)與 intrinsic(__sinf/__fdividef)之間取捨。intrinsic 有哪三個共同特性、受哪些浮點旗標影響?fdividef__fdividef 名字只差兩個底線,精度有何不同?把浮點取整成整數該用 rint 還是 round、為什麼?--use_fast_math 做什麼?


Question 15 - Pipeline、mbarrier 與 Cooperative Groups [recall]

__pipeline_memcpy_asyncsize_and_align 只能是哪些值、追蹤哪個方向的複製?tiled_partition<Size>Size 的限制?cg::reduce 何時走硬體加速?grid.sync() 為何不能用 <<<>>> 啟動、需要哪個 API 與哪個 CC?


Question 16 - Device Runtime 的 API 子集與 Stream 替代 [application]

你在 kernel 內(Dynamic Parallelism)要建 stream、做同步、配置記憶體。device runtime 建 stream 必須傳什麼 flag、用哪個 API?為何沒有 cudaStreamSynchronize、想確認子 kernel 完成該怎麼辦?cudaStreamFireAndForgetcudaStreamTailLaunch 的根本差異?device runtime 支援多 GPU 嗎?


Question 17 - CUDA C++ 記憶體模型:Thread Scope 與 Data Race [recall]

CUDA C++ 為何要在標準記憶體模型上加 thread scope?四個 scope 由大到小是哪些、thread_scope_device 的精確範圍?一個 atomic 操作「何時才真的是 atomic」?加上 scope 後的 data race 定義與後果為何?


Question 18 - CUDA C++ 執行模型:Forward Progress [analysis]

CUDA 對 device thread 提供哪種前向進度(forward progress)、其前提是什麼?某個 device thread 開始推進後,推進保證會「傳染」到哪個範圍?為什麼 host 端「在 spin-loop 之外只呼叫一次」cudaStreamQuery 不足以解開等待者,而「迴圈內反覆呼叫」就可以?兩個 kernel 放在不同 stream 等待彼此時為何可能 starvation?