CPU启动未完成的CUDA Kernel后,是否可执行上下文切换?
咱先把核心结论亮出来:完全可以进行上下文切换,这不仅是允许的,也是CUDA异步执行模型和操作系统进程调度机制共同支持的正常行为。
下面拆解一下上下文切换时的内部逻辑:
操作系统层面:CPU进程切换和GPU无关
操作系统的进程调度是独立于GPU执行的——不管GPU上的Kernel有没有跑完,只要调度条件满足(比如当前进程的时间片耗尽、有更高优先级进程需要运行),OS就会把当前进程从CPU核心上换下来,保存它的CPU上下文(寄存器状态、程序计数器、栈指针等),然后加载另一个进程的上下文让它执行。这一步操作完全不感知GPU的运行状态,OS只负责CPU侧的进程调度。GPU端:Kernel会继续独立执行
当CPU进程被切换走后,GPU上的Kernel会照常运行到完成。因为CUDA上下文是和CPU进程绑定的,只要进程没有被销毁,它对应的CUDA上下文就会被保留(如果GPU内存不足,部分上下文数据可能会被暂存到主机内存,但执行流不会中断)。GPU的SM(流式多处理器)会持续执行Kernel的线程块,直到所有任务完成。进程切回后的状态恢复
当被切换走的进程重新获得CPU时间片时,OS会恢复它的CPU上下文,进程可以继续执行自己的代码:- 如果之前的Kernel已经完成,进程可以直接读取结果;
- 如果Kernel还在运行,进程可以继续执行不依赖GPU结果的逻辑,或者后续调用
cudaDeviceSynchronize()、cudaStreamSynchronize()等同步API等待Kernel完成,甚至提交新的Kernel任务。
特殊场景:进程挂起/休眠
就算CPU进程被挂起(比如调用sleep())或者进入休眠状态,GPU上的Kernel也不会停止,会继续执行直到结束。只有当CPU进程被销毁时,对应的CUDA上下文才会被清理,未完成的Kernel才会被强制终止。
举个简单的例子:你启动一个CUDA Kernel去处理大矩阵乘法,然后进程开始执行本地的文件IO操作,这时候OS可能因为IO阻塞或者时间片到了把进程切换走,GPU会继续默默计算矩阵,等进程切回来后,要么IO已经做完可以等GPU结果,要么继续做其他事,完全不冲突。
内容的提问来源于stack exchange,提问作者sungjun cho

