【问题标题】:CUDA memcpy async is not returning immediatelyCUDA memcpy async 没有立即返回
【发布时间】:2014-01-14 06:58:08
【问题描述】:

以下是我的代码,它试图实现非阻塞 cuda 内存复制主机到设备。

for (i = 0; i < ldu; ++i)
{
     cudaMemcpyAsync(dA+i*num_row, &A+i*LDA,
         num_row*sizeof(double), cudaMemcpyHostToDevice,streams[0]) ; 

}

每个此类调用的平均时间约为 10 微秒。我尝试过需要 30 微秒的阻塞版本。 10 微秒,对于非阻塞调用来说似乎很多。 A 是使用 cudaHostalloc 分配的。我在配备 1 个 Tesla C2050 的机器上运行我的代码,并使用 cuda 5.5 版来编译代码。我读过 gpu PCI 传输延迟(与非阻塞调用有点无关,但要了解时间顺序)约为 5us。因此,非阻塞调用的返回时间为 10 us 有点偏高。我可以做些什么来加快速度?

我尝试过的几件事是,放置一个 openmp pragma(导致速度变慢),使用不同的流发送数据(平均时间大致相同)

【问题讨论】:

  • 这是在windows还是linux中?如果您只发出一个呼叫而不是一系列呼叫,您会测量什么时间?
  • 它在 linux 中。稍后我会回复你关于第二部分的信息
  • 对于单次调用,即如果我更改 ldu=1,则返回时间约为 3.5 us
  • 似乎有许多异步副本可以排队到单个流中,超过此排队性能会降低很多。这个数字似乎在 1000-10000 范围内。所以我猜,对于您的测试,ldu 在这个范围内。这里是my test。在 1000 个队列副本以下,平均开销小于 3us。 10000份以上,平均开销超过20us。但是,我相信您可以通过一次调用 cudaMemcpy2DAsync 来替换您的复制循环。

标签: optimization cuda parallel-processing gpu data-transfer


【解决方案1】:

我可以做些什么来加快速度?

我相信您可以将复制循环替换为:

cudaMemcpy2DAsync(dA, num_row*sizeof(double), &A, LDA*sizeof(double), num_row*sizeof(double), ldu, cudaMemcpyHostToDevice, streams[0]);

这应该会显着加快处理速度(至少从调用开销的角度来看)。

您可能需要稍微调整一下参数,因为您的名字让我有些困惑(也许您正在使用列优先存储)。 cudaMemcpy2DAsync 函数记录在 here

【讨论】:

  • 谢谢。我会尝试一下并发布我的结果。
  • 现在整个发送成本只有3.4 us左右,相当于发送一个列。
【解决方案2】:

Fermi gpus 每个方向只有一个复制引擎。所以,所有同方向的复制命令,无论是否异步,都会被序列化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2010-10-14
    • 2012-07-11
    • 1970-01-01
    相关资源
    最近更新 更多