【问题标题】:Replacing cudaMemcpy2D with cudaMemPrefetchAsync用 cudaMemPrefetchAsync 替换 cudaMemcpy2D
【发布时间】:2019-10-15 03:59:40
【问题描述】:

我正在尝试以与cudaMemcpy2DAsync() 提供的相同方式对驻留在统一内存中的数据进行异步内存传输(主机到设备),即为目标(设备)内存使用 pitch 值

但是,据我了解:

  • 我不能使用cudaMemcpy2DAsync(),因为它需要固定内存,并且使用cudaMallocManaged() 分配的统一内存块默认不固定,也不能手动固定。

  • 我不能使用cudaMemPrefetchAsync(),因为它只复制连续的内存块,而cudaMemcpy2DAsync() 包含根据给定间距值缓冲我的数据行的其他选项。

我的问题:

如何以异步方式传输 (a) 驻留在统一内存中的数据 (b) 从主机到设备,同时确保复制数据(c) 使用正确的音高值

我当前使用cudaMemcpy2D() 进行的传输看起来像这样:

cudaMemcpy2D( 
    dest_ptr, dest_pitch,         // dst address & pitch
    src_ptr, dim_x*sizeof(float)  // src address & pitch
    dim_x*sizeof(float), dim_y,   // transfer width & height
    cudaMemcpyHostToDevice ) );

(如您所见,源的音高实际上为零,而目的地的音高是dest_pitch——也许这有帮助?)

另一个麻烦是我自己不分配需要传输的数据,因此如果不创建额外的数据副本(这将是有问题的),我无法手动应用音高。

我的一个想法是简单地逐行复制数据。然而,这将意味着大量非常小的数据传输,这听起来有点可怕。在我的示例中,它将是 3,040,000 次传输,每次传输 304 字节。但如果传输在多个流中异步传播,那么在 Pascal 上可能没问题。..?

任何指针/想法将不胜感激!

【问题讨论】:

  • 您可能对托管内存感到困惑。由于您的统一内存根据定义是无音调的,因此如果源是统一内存分配(使用cudaMemPrefetchAsync 时它总是),那么尝试进行任何类型的音调复制是没有意义的。如果您想从主机上的单独 分配复制到统一的内存分配,只需使用cudaMemcpy2DAsync。但是,这似乎不适用于您的情况,因为您已经说过数据驻留在统一内存中。您应该在此处阐明分配源和目标的确切方式。
  • 感谢您的信息,并为迟到的答案道歉,我今天才看到您的回复。我不确定我是否理解为什么无法将音高副本放入无音高的内存中。它只是在复制时添加了一些填充,内存本身没有实际区别吗?但是,无论哪种方式,如果不可能进行投稿副本,那么这就是我的问题的答案。如果您想将此作为答案发布,那么我可以接受并关闭此问题。 (尽管由于某种原因它已经被否决了,所以无论如何它可能并不重要。)
  • 除非您在示例中准确说明源和目标的分配方式,否则我无法提供任何答案。

标签: c++ cuda unified-memory


【解决方案1】:

答案是您需要制作副本。具有统一内存的异步副本不支持音高,因为统一内存不支持音高。您可以将设备上预取的统一缓冲区复制到一个倾斜的内存区域,也可以将主机上的统一缓冲区复制到一个倾斜的内存区域,然后异步复制它。您不能同时满足所有三个条件(a、b 和 c)

【讨论】:

  • “具有统一内存的异步副本不支持音高,因为统一内存不支持音高。” - 谢谢,这是我缺少的信息。对不起,如果最初的问题似乎有点模糊!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-06
  • 2013-07-30
相关资源
最近更新 更多