2016-01-22 36 views
0

说我有一个函数,它需要一个设备指针并对它执行一些操作。然而这个工作更适合cpu,所以我在cpu上分配了一块内存,在cpu内存上执行一些操作,然后将它复制到gpu。事情是这样的:执行主机端malloc和异步主机到设备memcpy的典型方法

void func(void *dev_ptr, cudaStream_t stream) 
{ 
    void *host_ptr = malloc(100); 
    // do something on host_ptr 
    cudaMemcpyAsync(dev_ptr, host_ptr, 100, cudaMemcpyHostToDevice, stream); 
    free(host_ptr); 
} 

free调用是这里危险,因为memcpy的是异步复制可能不会在该点free被称为完成。我弄清楚,存在CUDA回调机制,所以我觉得下面的代码可能更合适:

void CUDART_CB callback_free(cudaStream_t, cudaError_t, void *userData) 
{ 
    free(userData); 
} 

void func(void *dev_ptr, cudaStream_t stream) 
{ 
    void *host_ptr = malloc(100); 
    // do something on host_ptr 
    cudaMemcpyAsync(dev_ptr, host_ptr, 100, cudaMemcpyHostToDevice, stream); 
    cudaStreamAddCallback(stream, callback_free, static_cast<void *>(host_ptr), 0); 
} 

问:

  1. 是它的规范的方法来完成这个任务?
  2. 如果我想host_ptr分配在堆栈而不是堆上怎么办?我不想在这里介绍不必要的cudaStreamSynchronize

在此先感谢。

+1

为什么你甚至在C++中使用'malloc'和'free'? –

+0

@AngryLettuce没关系......只是为了与'cudaMalloc'和'cudaFree'一致 –

回答

4

回答您的问题:

  1. 是它的规范的方法来完成这个任务?
    据我所知,这是唯一能够在没有显式同步调用的情况下做到这一点的方法。

  2. 如果我想host_ptr分配在堆栈而不是堆上怎么办?我不想在这里介绍不必要的cudaStreamSynchronize
    你不会介绍一个不必要的cudaStreamSynchronize电话,你会介绍一个必要的。在这种情况下停止堆栈变量超出范围的唯一方法是阻止,并且阻止的正确方法是调用cudaStreamSynchronize