【问题标题】:Canonical ways to perform host-side malloc and asynchronous host-to-device memcpy执行主机端 malloc 和异步主机到设备 memcpy 的规范方法
【发布时间】:2016-01-22 07:50:56
【问题描述】:

假设我有一个函数,它接受一个设备指针并在它上面做一些事情。不过这个job比较适合cpu,所以我在cpu上分配了一块内存,对cpu内存做一些操作,然后copy到gpu上。像这样的:

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

提前致谢。

【问题讨论】:

  • @AngryLettuce 没关系...只是为了与cudaMalloccudaFree 保持一致

标签: c++ asynchronous cuda


【解决方案1】:

回答您的问题:

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

  2. 如果我希望host_ptr 分配在堆栈上而不是堆上怎么办?我不想在这里介绍不必要的cudaStreamSynchronize
    您不会引入不必要的cudaStreamSynchronize 调用,而是引入必要的调用。在这种情况下,阻止堆栈变量超出范围的唯一方法是阻塞,而正确的阻塞方法是调用cudaStreamSynchronize

【讨论】:

    猜你喜欢
    • 2014-04-21
    • 2016-02-09
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 2023-01-11
    • 2012-02-09
    相关资源
    最近更新 更多