我正在尝试编写一些代码以确保停止所有 GPU 活动(特别是所有正在运行的线程)。我需要这样做以使用 dlclose 卸载模块,因此我需要确保主机和设备上的所有线程都已停止。
根据CUDA 文档,cudaDeviceSynchronize:
阻塞,直到设备完成所有先前请求的任务...如果为该设备设置了 cudaDeviceScheduleBlockingSync 标志,则主机线程将阻塞,直到设备完成其工作。
但是,当我设置阻塞同步标志并调用 cudaDeviceSynchronize 时,会产生一个新的主机线程,它在 cudaDeviceSynchronize 返回后仍在运行。这与我想要达到的目标相反。
此行为在示例程序中演示:
#include <iostream>
void initialiseDevice()
{
cudaError result = cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync);
if (cudaSuccess == result)
std::cout << "Set device flags." << std::endl;
else
std::cout << "Could not set device flags. (" << result << ")"
<< std::endl;
}
void synchroniseDevice()
{
cudaError result = cudaDeviceSynchronize();
if (cudaSuccess == result)
std::cout << "Device synchronise returned success." << std::endl;
else
std::cout << "Device synchronise returned error. (" << result << ")"
<< std::endl;
}
int main()
{
initialiseDevice();
sleep(1);
synchroniseDevice(); // new thread is spawned here
sleep(1); // new thread is still running here!
return 0;
}
如果我用 编译这个程序nvcc -g main.cu
,并在 gdb 中运行它,调用info threads
显示在 cudaDeviceSynchronize 返回后有两个线程在运行。
在 gdb 中运行时在 cudaDeviceSynchronise 之后的行上输出信息线程:
(gdb) info threads
Id Target Id Frame
2 Thread 0x7ffff5b8b700 (LWP 28458) "a.out" 0x00007ffff75aa023 in select
() at ../sysdeps/unix/syscall-template.S:82
* 1 Thread 0x7ffff7fd4740 (LWP 28255) "a.out" main () at cuda_test.cu:30
谁能帮我理解为什么 cudaDeviceSynchronize 会产生一个新线程,以及为什么线程在调用返回后仍在运行?
谁能指出我正确的方向来帮助我找到一种阻止方法,直到所有设备和主机活动/线程完成?