由cudaMalloc |生成的新线程行为?

时间:2016-05-30 07:21:19

标签: multithreading cuda cuda-gdb

groupByKey似乎在调用时产生了一个线程,即使它是异步的。在使用cudaMalloc进行调试期间观察到了这一点。 cudaMalloc called within alloc_mem_GPU spawning New Thread

还需要一段时间才能返回。

虽然作为一个不同的LWP,但在程序结束时退出了相同的线程。

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

1 个答案:

答案 0 :(得分:2)

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

您看到这与cudaMalloc相关联,因为我猜这是第一个触发任何需要进行的设置/回调以使用户空间驱动程序支持工作的API。您应该注意到只有第一个调用才会产生一个线程。后续的电话没有。并且线程在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