【问题标题】:cudaMemcpyAsync execution is delayed for some reasoncudaMemcpyAsync 执行由于某种原因被延迟
【发布时间】:2017-03-20 11:58:42
【问题描述】:

我正在尝试使用流来运行 H2D 副本和内核并行运行。 为此,我创建了 2 个带有 cudaStreamNonBlocking 标志的流。 在一个循环中,我执行以下伪代码:

// pseudocode
cudaMemcpy(data[0]);
streamIdx = 0;

while(1)
{
    // prepare for next loop
    cudaMemcpyAsync(dData[!streamIdx], hData[!streamIdx], 
        stream[!streamIdx]);
    // run current loop
    cudaStreamSynchronize(stream[streamIdx]);
    kernel1<stream[streamIdx]>();
    kernel2<stream[streamIdx]>();
    streamIdx = !streamIdx;
}

主机内存已固定。 结果是每秒 cudaMemcpyAsync 都会延迟,这会导致代码运行速度变慢。 见图:

我设法通过在复制的同一流上运行假内核来欺骗复制引擎,只是为了让它立即运行。

有没有什么NORMAL方法让GPU立即执行cudaMemcpyAsync?

我使用 GeForce GTX 1060 6GB GPU

【问题讨论】:

  • 这可能是 wddm 命令批处理。你在窗户上吗?如果是这样,则没有 正常 方法可以避免它。异常方法包括重组代码,和/或使用额外的、可能是不必要的命令,例如额外的内核启动或额外的 cudaAPI 调用(如 cudaStreamQuery),以便在需要时刷新命令队列。或者您可以切换到 linux,或者您可以切换到可以在 Windows 上设置为 TCC 模式的 GPU(GeForce gpus 不能,除了泰坦)。
  • 我确实使用 Windows。 cudaStreamQuery 用于刷新队列。谢谢
  • 主机端内存是如何分配的?

标签: optimization cuda cuda-streams


【解决方案1】:

cudaStreamSynchronize 强制 CPU 阻塞等待流空闲。在您的情况下,CPU 无需阻塞,而只需继续为 GPU 供电。

像这样重构你的代码:

while(1)
{
    // prepare for next loop
    cudaMemcpyAsync(dData[streamIdx], hData[streamIdx], stream[streamIdx]);
    // run current loop
    kernel1<stream[streamIdx]>();
    kernel2<stream[streamIdx]>();
    streamIdx = !streamIdx;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多