【发布时间】:2012-11-15 18:55:27
【问题描述】:
我正在尝试编写一些代码来确保所有 GPU 活动(尤其是所有正在运行的线程)都停止。我需要这样做以使用 dlclose 卸载模块,因此我需要确保主机和设备上的所有线程都已停止。
根据CUDA documentation,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 会产生一个新线程,以及为什么该线程在调用返回后仍在运行?
谁能指出我正确的方向,帮助我找到一种阻止方法,直到所有设备和主机活动/线程都完成?
【问题讨论】:
-
cudaDeviceSynchronize() 阻塞,直到所有 device 活动完成。 gdb info threads 命令提供有关主机活动的信息。 cudaDeviceSynchronize() 不保证与主机线程有关的任何事情。如果你想query device threads,正确的命令是
info cuda threads(在 cuda-gdb 中)。您列出的其中一个线程似乎是由系统调用启动的。这可能会发生。另一个线程似乎是被 cudaDeviceSynchronize() 阻塞的线程。 -
@RobertCrovella 为什么你不把它放在答案而不是评论上:)?
-
罗伯特,感谢您的评论。在那种情况下,我想我问的问题并不正确。我想做的是停止设备和主机上的所有线程。 cudaDeviceSynchronize 可能会停止所有设备线程,但它会始终启动一个新的主机线程,该线程在它返回后继续运行。我需要所有线程来完成。我将编辑问题。
-
@alex 要停止所有主机线程,是否需要终止应用程序?
-
@dreamcrash 对于您的问题,我真的没有很好的答案。我并不总是确定什么是答案。在这种情况下,似乎亚历克斯的问题实际上是他编辑的。关于 cudaDeviceSynchronize 的问题是辅助性的。
标签: multithreading cuda