cudaMalloc 生成的新线程 |行为?

New Thread spawned by cudaMalloc | Behaviour?

cudaMalloc 似乎在调用时生成了一个线程,即使它是异步的。这是在使用 cuda-gdb 调试期间观察到的。

return也花了点时间。

同一个线程在程序结束时作为不同的 LWP 退出。

有人可以解释这种行为吗?

线程不是由 cudaMalloc 专门生成的。用户端 CUDA 驱动程序 API 库似乎在具有 CUDA 上下文生命周期的惰性上下文设置期间的某个阶段生成线程。确切的过程没有公开记录。

你看到这与 cudaMalloc 相关联,因为我猜这是第一个 API 触发任何 setup/callbacks 需要完成的工作,以使用户空间驱动程序支持工作。您应该注意到只有第一次调用会产生一个线程。随后的调用不会。并且线程在 CUDA 上下文的生命周期内保持活动状态,之后它们将被终止。您可以通过在程序执行的任何时候调用 cudaDeviceReset 来触发显式线程销毁。

这是一个简单的例子,它演示了 cudaMemcpyToSymbol 从驱动程序 API 库触发线程生成,而不是 cudaMalloc:

__device__ float someconstant;

int main()
{
    cudaSetDevice(0);
    const float x = 3.14159f;
    cudaMemcpyToSymbol(someconstant, &x, sizeof(float));
    for(int i=0; i<10; i++) {
        int *x;
        cudaMalloc((void **)&x, size_t(1024));
        cudaMemset(x, 0, 1024);
        cudaFree(x);
    }
    return int(cudaDeviceReset());
}

在 gdb 中我看到了这个:

(gdb) tbreak main
Temporary breakpoint 1 at 0x40254f: file gdb_threads.cu, line 5.
(gdb) run
Starting program: /home/talonmies/SO/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Temporary breakpoint 1, main () at gdb_threads.cu:5
5       cudaSetDevice(0);
(gdb) next
6       const float x = 3.14159f;
(gdb) next
7       cudaMemcpyToSymbol(someconstant, &x, sizeof(float));
(gdb) next
[New Thread 0x7ffff5eb5700 (LWP 14282)]
[New Thread 0x7fffed3ff700 (LWP 14283)]
8       for(int i=0; i<10; i++) {
(gdb) info threads
  Id   Target Id         Frame 
  3    Thread 0x7fffed3ff700 (LWP 14283) "a.out" pthread_cond_timedwait@@GLIBC_2.3.2 ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
  2    Thread 0x7ffff5eb5700 (LWP 14282) "a.out" 0x00007ffff74d812d in poll () at ../sysdeps/unix/syscall-template.S:81
* 1    Thread 0x7ffff7fd1740 (LWP 14259) "a.out" main () at gdb_threads.cu:8

(gdb) thread apply all bt

Thread 3 (Thread 0x7fffed3ff700 (LWP 14283)):
#0  pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
#1  0x00007ffff65cad97 in ?? () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#2  0x00007ffff659582d in ?? () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#3  0x00007ffff65ca4d8 in ?? () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#4  0x00007ffff79bc182 in start_thread (arg=0x7fffed3ff700) at pthread_create.c:312
#5  0x00007ffff74e547d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Thread 2 (Thread 0x7ffff5eb5700 (LWP 14282)):
#0  0x00007ffff74d812d in poll () at ../sysdeps/unix/syscall-template.S:81
#1  0x00007ffff65c9953 in ?? () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#2  0x00007ffff66571ae in ?? () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#3  0x00007ffff65ca4d8 in ?? () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#4  0x00007ffff79bc182 in start_thread (arg=0x7ffff5eb5700) at pthread_create.c:312
#5  0x00007ffff74e547d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Thread 1 (Thread 0x7ffff7fd1740 (LWP 14259)):
#0  main () at gdb_threads.cu:8