CUDA 的檢查點和恢復功能通過名為 cuda-checkpoint 的命令行實用程序公開,該實用程序可用于在正在運行的 Linux 進程中以透明方式檢查點和恢復 CUDA 狀態,同時也可以與開源檢查點實用程序 CRIU(用戶空間中的檢查點/恢復)相結合,以完全檢查點 CUDA 應用程序。
檢查點概述
透明的每進程檢查點在虛擬機檢查點和應用程序驅動檢查點之間提供了一個中間地帶。每進程檢查點可與容器結合使用,檢查復雜應用程序的狀態,從而促進諸如以下用例。
- 容錯,帶有定期檢查點
- 通過檢查搶占性任務,搶占單節點上低優先級工作的先機
- 通過遷移實現集群調度

CRIU
CRIU(用戶空間中的檢查點/恢復)是適用于 Linux 的開源檢查點實用程序,在 NVIDIA 外部進行維護,可以檢查點和恢復進程樹。
CRIU 通過一個名為criu
并通過檢查點和恢復與進程關聯的每個內核模式資源來運行。這些資源包括:
- 匿名內存
- 線程
- 常規文件
- 插槽
- 檢查點進程之間的管道
由于這些資源的行為由 Linux 指定,并且獨立于底層硬件,CRIU 知道如何檢查并恢復這些資源。
相比之下,NVIDIA GPU 提供的功能超出了標準 Linux 內核的功能,因此 CRIU 無法管理它們。cuda-checkpoint
增加了這項功能,可以與 CRIU 一起用于檢查點和恢復 CUDA 應用程序。
CUDA 檢查點
cuda-checkpoint
檢查點并恢復單個 Linux 進程的 CUDA 狀態。它支持顯示驅動程序版本 550 及更高版本,可以從 /bin 目錄 下載。
localhost$ cuda-checkpoint --help CUDA checkpoint and restore utility. Toggles the state of CUDA within a process between suspended and running. Version 550.54.09. Copyright (C) 2024 NVIDIA Corporation. All rights reserved. --toggle --pid <value> Toggle the state of CUDA in the specified process. --help Print help message. |
cuda-checkpoint 二進制文件可以在掛起和運行之間切換由 PID 指定的進程的 CUDA 狀態,一種從運行到掛起的過渡稱為掛起,相反的過渡稱為恢復。
進程的 CUDA 狀態最初正在運行。當cuda-checkpoint
在用于在進程中掛起 CUDA 時,它遵循以下步驟:
請提供 Input Content,我將根據 Source Content 對其進行校對和修改,以確保內容的正確性和清晰性。![]() |
任何啟動工作、管理資源或以其他方式影響 GPU 狀態的 CUDA 驅動程序 API 均會被鎖定。 |
請提供 Input Content,我將對其進行潤色和校對。![]() |
已提交的 CUDA 工作 (包括流回調) 已完成。 |
![]() |
設備內存復制到主機,再復制到由 CUDA 驅動程序管理的分配中。 |
請提供 Input Content,我將根據 Source Content 對其進行校對和修改,以確保句子表達正確、意思明確。![]() |
所有 CUDA GPU 資源均已發布。 |
cuda-checkpoint
用于掛起 CUDAcuda-checkpoint
不會掛起 CPU 線程,這些線程可以繼續安全地與 CUDA 交互,方式如下:調用運行時或驅動程序 API,這些 API 可能會阻塞直到 CUDA 恢復;或訪問由 cudaMallocHost
和類似 API 分配的主機內存,這些內存仍然有效。
掛起的 CUDA 進程不再直接指操作系統級別的任何 GPU 硬件,因此可能會由 CPU 檢查點實用程序 (例如 CRIU) 進行檢查點檢查。
當進程的 CUDA 狀態恢復時,使用cuda-checkpoint
它遵循以下步驟:
請提供 Input Content,我將對其進行潤色和校對。 | 該過程會重新獲取 GPU。 |
請提供 Input Content,我將對其進行修改和潤色,以確保其語句正確、意思明確。![]() |
系統會將設備內存復制回 GPU,并將 GPU 內存映射恢復到原始地址。 |
請提供 Input Content,我將根據 Source Content 對其進行校對和修改,以確保語言流暢、意思明確。![]() |
流和上下文等 CUDA 對象將被恢復。 |
請提供 Input Content,我將根據 Source Content 對其進行校對和修改,以確保內容的正確性和清晰性。![]() |
CUDA 驅動程序 API 已解鎖。 |
cuda-checkpoint
此時,CUDA 會調用 unblock,CUDA 即可重新開始在 GPU 上運行。
檢查點示例
此示例使用 cuda-checkpoint
和 CRIU 來檢查名為 counter
的 CUDA 應用程序。每當 counter
收到數據包時,它都會增加 GPU 內存并使用更新后的值進行回復。示例代碼也可以在 GitHub 庫中找到。
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 10000 __device__ int counter = 100; __global__ void increment() { counter++; } int main( void ) { cudaFree(0); int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); sockaddr_in addr = {AF_INET, htons(PORT), inet_addr( "127.0.0.1" )}; bind(sock, (sockaddr *)&addr, sizeof addr); while ( true ) { char buffer[16] = {0}; sockaddr_in peer = {0}; socklen_t inetSize = sizeof peer; int hCounter = 0; recvfrom(sock, buffer, sizeof buffer, 0, (sockaddr *)&peer, &inetSize); increment<<<1,1>>>(); cudaMemcpyFromSymbol(&hCounter, counter, sizeof counter); size_t bytes = sprintf (buffer, "%d\n" , hCounter); sendto(sock, buffer, bytes, 0, (sockaddr *)&peer, inetSize); } return 0; } |
您可以構建counter
應用程序,nvcc
.
localhost$ nvcc counter.cu -o counter |
保存counter
供后續命令參考的 PID:
localhost# PID=$! |
發送counter
數據包并觀察返回值。初始值為 100,但響應為 101,表明 GPU 顯存自初始化以來發生了變化。
localhost# echo hello | nc -u localhost 10000 -W 1 101 |
使用nvidia-smi
確認counter
在 GPU 上運行:
localhost# nvidia-smi --query --display=PIDS | grep $PID Process ID : 298027 |
使用cuda-checkpoint
暫停counter
CUDA 狀態:
localhost# cuda-checkpoint --toggle --pid $PID |
使用nvidia-smi
確認counter
不再在 GPU 上運行:
localhost# nvidia-smi --query --display=PIDS | grep $PID |
創建用于保存檢查點圖像的目錄:
localhost# mkdir -p demo |
使用criu
檢查點counter
:
localhost# criu dump --shell-job --images-dir demo --tree $PID [1]+ Killed ./counter |
確認counter
不再運行:
localhost# ps --pid $PID PID TTY TIME CMD |
使用criu
來恢復counter
:
localhost# criu restore --shell-job --restore-detached --images-dir demo |
使用cuda-checkpoint
繼續counter
CUDA 狀態:
localhost# cuda-checkpoint --toggle --pid $PID |
現在counter
然后向其發送另一個數據包。響應為 102,表明先前的 GPU 操作已正確持久化。
localhost# echo hello | nc -u localhost 10000 -W 1 102 |
功能
截至顯示驅動版本 550,檢查點和恢復功能仍在積極開發中。特別是cuda-checkpoint
具有以下特征:
- 僅限 x64、
- 作用于單個進程而非進程樹。
- 不支持 UVM 或 IPC 顯存。
- 不支持 GPU 遷移。
- 等待已提交的 CUDA 工作完成,然后再完成檢查點。
- 如果在檢查點或恢復期間遇到錯誤 (例如存在 UVM 分配),請勿嘗試保持進程處于良好狀態。
這些限制將在后續的顯示驅動程序版本中解決,并且不需要更新 cuda-checkpoint 實用程序本身。cuda-checkpoint 實用程序公開了驅動程序中包含的功能。
總結
cuda-checkpoint 實用程序與 CRIU 結合后,可實現 Linux 應用程序的每進程透明檢查點。有關更多信息,請參閱 /NVIDIA/cuda-checkpoint GitHub 存儲庫。
嘗試檢查點counter
在您自己的機器上運行應用程序或任何其他兼容的 CUDA 應用程序!
?