CUDA 環境變數 (CUDA Environment Variables)

重點總覽

CUDA 提供一組環境變數,在「不改程式碼」的前提下調整 device 列舉、JIT 編譯快取、執行行為、module 載入策略與錯誤記錄。與 MPS 相關的變數另載於 GPU Deployment and Management Guide,本篇不涵蓋。下表濃縮五大類最該記的變數。

分類 代表變數 一句話作用
Device Enumeration CUDA_VISIBLE_DEVICES 控制哪些 GPU 可見、列舉順序(決定 ordinal)
Device Enumeration CUDA_DEVICE_ORDER FASTEST_FIRST(預設)或 PCI_BUS_ID 列舉順序
Device Enumeration CUDA_MANAGED_FORCE_DEVICE_ALLOC 強制 Unified Memory 用 device memory 實體儲存
JIT Compilation CUDA_CACHE_DISABLE / _PATH / _MAXSIZE 控制 on-disk PTX→CUBIN JIT 快取的開關/路徑/大小
JIT Compilation CUDA_FORCE_PTX_JIT / CUDA_DISABLE_PTX_JIT 強制走 PTX JIT / 強制只用 embedded CUBIN
Execution CUDA_LAUNCH_BLOCKING =1 關閉非同步執行,方便對齊錯誤發生點除錯
Execution CUDA_DEVICE_MAX_CONNECTIONS 並行 work queue 數(1–32,預設 8),避免 false dep
Execution CUDA_AUTO_BOOST(deprecated) 已棄用,改用 nvidia-smi/NVML
Module Loading CUDA_MODULE_LOADING LAZY(預設)/ EAGER 控制 kernel 載入時機
Error Log Management CUDA_LOG_FILE 把白話錯誤訊息輸出到 stdout/stderr/檔案
共同慣例

多數開關型變數以 1 觸發其特殊行為(停用/強制/暫停等)、0 為預設;字串型變數(如 CUDA_DEVICE_ORDERCUDA_MODULE_LOADING)則取列舉值。

Device Enumeration and Properties

CUDA_VISIBLE_DEVICES

控制哪些 GPU 對 CUDA 應用程式可見,以及它們被列舉的順序。

識別形式 說明
Integer index GPU 在系統中的序號(同 nvidia-smi,從 0 起)。如 =2,1 使 device 0 不可見,且 device 2 列在 1 之前
GPU UUID 字串 格式同 nvidia-smi -L,如 GPU-8932f937-...;允許縮寫,只需足以唯一識別的前綴(如 GPU-8932f937
MIG 識別 MIG-<GPU-UUID>/<GPU instance ID>/<compute instance ID>僅支援單一 MIG instance 列舉
遇到無效 index 會「截斷」清單

若清單中出現無效 index,只有「排在無效 index 之前」的 device 可見。例如 CUDA_VISIBLE_DEVICES=0,2,-1,1 只有 device 0 與 2 可見,device 1 因排在無效的 -1 之後而不可見。

ordinal 與可見性的關係:

CUDA_VISIBLE_DEVICES=2,1
  ordinal 0 ─► 實體 device 2   (列舉第一)
  ordinal 1 ─► 實體 device 1
  cudaSetDevice(0) → 目前 device = 實體 device 2

CUDA_DEVICE_ORDER

控制 CUDA 列舉可用 device 的順序。

取值 行為
FASTEST_FIRST 用簡單啟發法由快到慢列舉(預設
PCI_BUS_ID 依 PCI bus ID 由小到大列舉(可用 nvidia-smi --query-gpu=...

CUDA_MANAGED_FORCE_DEVICE_ALLOC

改變多 GPU 系統中 Unified Memory 的實體儲存方式。取值為數值,零或非零。

JIT Compilation

這組變數控制 on-disk Just-In-Time (JIT) 編譯快取與 PTX/CUBIN 的取捨。

變數 取值 / 預設 作用
CUDA_CACHE_DISABLE 1 停用 / 0 啟用(預設) 停用後每次執行都重新做 PTX→CUBIN 編譯(除非 binary 內已有對應架構的 CUBIN)
CUDA_CACHE_PATH 快取目錄絕對路徑 預設:Windows %APPDATA%\NVIDIA\ComputeCache;Linux ~/.nv/ComputeCache
CUDA_CACHE_MAXSIZE bytes;上限 4294967296 (4 GiB) 預設桌機/伺服器 1073741824 (1 GiB)、嵌入式 268435456 (256 MiB);超大 binary 不快取
CUDA_FORCE_PTX_JIT / CUDA_FORCE_JIT 1 強制 / 0 預設 忽略 embedded CUBIN,改 JIT 編譯 embedded PTX
CUDA_DISABLE_PTX_JIT / CUDA_DISABLE_JIT 1 停用 / 0 預設 停用 embedded PTX 的 JIT,只用相容的 embedded CUBIN
CUDA_FORCE_PRELOAD_LIBRARIES 1 強制 / 0 預設 初始化時預載 NVVM 與 JIT 所需 library

重點說明:

兩組 override 規則一起記

*_PTX_JIT 版本永遠覆蓋對應的 *_JIT 版本:CUDA_FORCE_PTX_JIT > CUDA_FORCE_JITCUDA_DISABLE_PTX_JIT > CUDA_DISABLE_JIT

Execution

變數 取值 / 預設 作用
CUDA_LAUNCH_BLOCKING 1 關閉非同步 / 0 非同步(預設) =1 讓 GPU 工作從 CPU 視角同步執行,錯誤可對齊到觸發的那個 API 呼叫,利於除錯
CUDA_DEVICE_MAX_CONNECTIONS 1–32 connections,預設 8(無 MPS) 並行 compute 與 copy engine 的 work queue 數,兩者一起設
CUDA_DEVICE_MAX_COPY_CONNECTIONS 1–32 connections,預設 8(無 MPS) 只影響 compute capability 8.0+;只設 copy connections
CUDA_SCALE_LAUNCH_QUEUES 0.25x / 0.5x / 2x / 4x launch queue(command buffer)大小縮放;其他值一律視為 1x
CUDA_GRAPHS_USE_NODE_PRIORITY 0 繼承 stream(預設)/ 1 用 node 控制 CUDA graph 執行優先序
CUDA_DEVICE_WAITS_ON_EXCEPTION 0 預設 / 1 暫停 =1 device 端 exception 發生時暫停等待,便於 attach cuda-gdb 檢視 live GPU state
CUDA_DEVICE_DEFAULT_PERSISTING_L2_CACHE_PERCENTAGE_LIMIT 0–100,預設 0 L2 cache 保留給 persisting access 的比例
CUDA_DISABLE_PERF_BOOST 1 停用 / 0 預設(僅 Linux) 不提升 device performance state,改以 heuristic 隱式選 pstate
CUDA_AUTO_BOOST(deprecated) GPU clock auto boost;已棄用

重點說明:

CUDA_LAUNCH_BLOCKING 是除錯工具,不是效能設定

關閉非同步執行會讓程式變慢;它的價值在於「讓 CUDA API 錯誤剛好在觸發它的那個呼叫被觀察到」,平時不應開啟。

Module Loading

控制 CUDA runtime 如何載入 module(device code 的初始化時機)。

變數 取值 作用
CUDA_MODULE_LOADING DEFAULT(=LAZY) / LAZY / EAGER 控制 kernel 的載入時機
CUDA_MODULE_DATA_LOADING DEFAULT(=LAZY) / LAZY / EAGER 控制 module 資料載入;未設則繼承 CUDA_MODULE_LOADING
CUDA_BINARY_LOADER_THREAD_COUNT 整數,預設 0(=1 個 thread) 載入 device binary 時使用的 CPU thread 數

LAZY vs EAGER

模式 載入時機 特性
LAZY 延後到取得 function handle CUfunccuModuleGetFunction()/cuKernelGetFunction());CUBIN 資料在首個 kernel 載入或首個變數被存取時才載入 降低 startup 時間與 GPU 記憶體佔用;首次呼叫載入,之後無額外開銷
EAGER 程式初始化即完整載入;CUBIN/FATBIN/PTX 的所有 kernel 與資料在對應的 cuModuleLoad* / cuLibraryLoad* 呼叫時全部載入 startup 時間與 GPU 記憶體佔用較高;kernel launch 開銷可預測
CUDA_MODULE_DATA_LOADING 是「資料層」的互補設定

它與 kernel 導向的 CUDA_MODULE_LOADING 互補,不影響 kernel 本身的 LAZY/EAGER。未設定時,資料載入行為繼承自 CUDA_MODULE_LOADING。注意 lazy 的資料載入可能需要 context synchronization,反而拖慢 concurrent execution。

CUDA_BINARY_LOADER_THREAD_COUNT 設為 0 時,使用的 CPU thread 數採預設值 1。

CUDA Error Log Management

CUDA_LOG_FILE

指定一個位置,讓「有回傳錯誤的、受支援的 CUDA API 呼叫」在錯誤發生時印出描述性錯誤訊息。

範例:以無效 grid 設定啟動 kernel(如 kernel<<<1, dim3(1,1,128)>>>(...))會失敗,cudaGetLastError() 只回傳通用的 invalid configuration argument。但若設了 CUDA_LOG_FILE,log 中會出現白話訊息:

[CUDA][E] Block Dimensions (1,1,128) include one or more values
that exceed the device limit of (1024,1024,64)

如此即可輕易判斷是 block 的 z 維度超標。

與第四章 Error Log Management 對照

CUDA_LOG_FILE 只是「啟用」描述性 log 的入口;更完整的 log 輸出/iterator/callback API 與限制,見 04-CUDA-Features/10-Lazy-Loading-and-Error-Log

考試/測驗重點

題型 關鍵答案
CUDA_VISIBLE_DEVICES 未設 / 設空字串? 未設=全部可見;空字串=全部不可見
CUDA_VISIBLE_DEVICES 三種識別形式? integer index、GPU UUID(可縮寫前綴)、MIG(僅單一 instance)
CUDA_VISIBLE_DEVICES=0,2,-1,1 哪些可見? 只有 0 與 2;遇無效 index 即截斷,之後的都不可見
CUDA_VISIBLE_DEVICES=2,1cudaSetDevice(0) 設實體 device 2(列舉最前、ordinal 0);count 只含可見 device
CUDA_DEVICE_ORDER 預設值? FASTEST_FIRST(由快到慢的啟發法);另一選項 PCI_BUS_ID
CUDA_MANAGED_FORCE_DEVICE_ALLOC 非零的前提? 所有支援 managed memory 的 device 須 P2P 相容,否則 cudaErrorInvalidDevice
CUDA_CACHE_DISABLE 預設與效果? 預設 0(啟用快取);=1 每次重編 PTX→CUBIN,初次載入變慢
JIT 快取預設大小與上限? 桌機/伺服器 1 GiB、嵌入式 256 MiB;上限 4 GiB
JIT 快取預設路徑? Windows %APPDATA%\NVIDIA\ComputeCache;Linux ~/.nv/ComputeCacheCUDA_CACHE_PATH 可改)
CUDA_FORCE_PTX_JITCUDA_FORCE_JIT 誰覆蓋誰? CUDA_FORCE_PTX_JIT 覆蓋 CUDA_FORCE_JIT
CUDA_DISABLE_PTX_JITCUDA_DISABLE_JIT 誰覆蓋誰? CUDA_DISABLE_PTX_JIT 覆蓋 CUDA_DISABLE_JIT
CUDA_FORCE_PRELOAD_LIBRARIES=1 的用途? 預載 NVVM/JIT library,避免某些多執行緒 deadlock;代價是記憶體與初始化時間增加
CUDA_LAUNCH_BLOCKING=1 何用? 關非同步,讓錯誤對齊觸發的 API 呼叫,方便除錯;會變慢
CUDA_DEVICE_MAX_CONNECTIONS 範圍/預設/問題? 1–32、預設 8;不足會因 work queue 共用造成 false dependency 序列化
CUDA_DEVICE_MAX_COPY_CONNECTIONS 適用對象與覆蓋關係? 僅 compute capability 8.0+;兩者都設時覆蓋 CUDA_DEVICE_MAX_CONNECTIONS 的 copy
CUDA_SCALE_LAUNCH_QUEUES 合法值? 0.25x/0.5x/2x/4x;其他值一律當 1x
CUDA_GRAPHS_USE_NODE_PRIORITY 0 vs 1? 0 繼承 stream 優先序(預設);1 用 per-node 優先序當排程提示,並覆蓋 cudaGraphInstantiateFlagUseNodePriority
CUDA_DEVICE_WAITS_ON_EXCEPTION=1 效果? device exception 時暫停,可 attach cuda-gdb 檢視 live GPU state
L2 persisting 限制變數的條件? compute capability 8.0+ 且用 MPS;須在 nvidia-cuda-mps-control -d 前設;0–100,預設 0
CUDA_DISABLE_PERF_BOOST 平台限制? 僅 Linux;=1 不提升 device performance state,改以 heuristic 隱式選 pstate,可能降功耗但部分情境 latency 較高
CUDA_AUTO_BOOST 狀態? 已棄用;改用 nvidia-smi --applications-clocks 或 NVML
CUDA_MODULE_LOADING 預設與差異? 預設 LAZY;LAZY 降 startup/記憶體、首呼叫載入;EAGER 啟動全載、launch 開銷可預測
CUDA_MODULE_DATA_LOADING 與前者關係? 互補的資料層設定;不影響 kernel LAZY/EAGER;未設則繼承 CUDA_MODULE_LOADING
CUDA_BINARY_LOADER_THREAD_COUNT=0 代表? 採預設 1 個 CPU thread
CUDA_LOG_FILE 合法取值? stdoutstderr,或合法檔案路徑