2016-05-30 107 views
0

cudaMalloc似乎在被調用時產生了一個線程,即使它是異步的。這在使用cuda-gdb的調試期間被觀察到。 cudaMalloc called within alloc_mem_GPU spawning New Thread由cudaMalloc產生的新線程行爲?

它也需要一段時間才能返回。

在程序結束時退出了相同的線程,但是作爲不同的LWP。

有人可以解釋這種行爲嗎?

回答

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" [email protected]@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 [email protected]@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 
+0

它是如何一個_lazy_建立 ?線程是不是立即產生? – kesari

+0

爲什麼這是一個社區維基? – kesari

+1

@kesari:這是懶惰的,因爲上下文創建('cudaSetDevice'調用)不會產生線程,即使上下文在該點處處於活動狀態。只有當需要線程的操作被調用時纔會產生它們。而我最近的答案是社區wiki的答案。這就是我選擇貢獻的方式 – talonmies