【发布时间】:2022-01-01 23:28:07
【问题描述】:
#include <cstdio>
__global__ void loop(void) {
int smid = -1;
if (threadIdx.x == 0) {
asm volatile("mov.u32 %0, %%smid;": "=r"(smid));
printf("smid: %d\n", smid);
}
while (1);
}
int main() {
loop<<<1, 32>>>();
cudaDeviceSynchronize();
return 0;
}
这是我的源代码,内核只是在线程索引为0时打印smid然后进入无限循环,主机只是调用之前的cuda内核并等待它。我在 2 种不同的配置下进行了一些实验,如下所示:
- 1。 GPU(Geforce 940M) 操作系统(Ubuntu 18.04) MPS(启用) CUDA(v11.0)
- 2。 GPU(Geforce RTX 3050Ti Mobile) 操作系统(Ubuntu 20.04) MPS(启用) CUDA(v11.4)
实验 1:当我在 配置 1 下运行此代码时,GUI 系统似乎被冻结,因为无法再观察到任何图形响应,但是当我按下 ctrl +c,当 CUDA 进程被杀死时,这种现象就会消失。
实验2:当我在配置2下运行这段代码时,系统似乎运行良好,没有任何异常现象,smid的输出如smid: 2\n可以显示。
实验 3:当我更改块配置 loop<<<1, 1024>>> 并在 配置 2 下运行此新代码两次时,我得到相同的 smid 输出,例如 smid: 2\nsmid: 2\n .(对于Geforce RTX 3050Ti Mobile,SM数量为20,每个多处理器的最大线程数为1536,每个块的最大线程数为1024。)
我对这些结果感到困惑,以下是我的问题:
- 1、为什么配置1下系统不输出smid?
- 2. 为什么在配置 1 下 GUI 系统似乎卡住了?
- 3. 与实验1不同,为什么实验2正常输出smid?
- 4、第三次实验,block配置达到1024个线程,这意味着不能将两个不同的block调度到同一个SM。在 MPS 环境下,所有的 CUDA 上下文将合并到一个 CUDA 上下文中,并且不再使用时间片共享 GPU 资源,但是为什么我在第三次实验中仍然得到相同的 smid?(此外,我将网格配置更改为 10 并运行它两次,smid 从 0 到 19 变化,每个 smid 只出现一次!)
【问题讨论】:
-
在没有无限循环的配置 1 中会发生什么。那你得到一个小输出吗?是否可以在内核调用后写入内核中的内存位置并将其复制到主机以创建内核的副作用(printf 除外)?
-
行为差异有多少来自驱动程序、编译器、硬件?能否为这两种架构编译或交换显卡?
-
感谢您的回复@Sebastian,在没有无限循环的配置 1 中,我可以获得 smid 输出。至于将smid从设备复制到主机,我稍后再试。
-
配置1的nvidia驱动在440左右(我记不太清楚了),配置2的驱动是495。编译器都是g++-8。也许我可以在CUDAv11.4下为sm_50构建代码,我稍后会尝试。 (Geforce 940M 的计算能力为 5.0,但在 cuda11.0 中有警告说 sm_50 可能在进一步的 CUDA 版本中被弃用)