【问题标题】:cudaMemcpy & blockingcudaMemcpy & 阻塞
【发布时间】:2013-04-12 17:21:04
【问题描述】:

我对一些关于阻塞和 cudaMemcpy 的 cmets 感到困惑。据我了解,Fermi HW 可以同时执行内核并执行 cudaMemcpy。

我读到 Lib func cudaMemcpy() 是一个阻塞函数。这是否意味着 func 将阻止进一步执行,直到副本完全完成?或者这是否意味着在之前的内核完成之前不会开始复制?

例如此代码是否提供相同的阻塞操作?

SomeCudaCall<<<25,34>>>(someData);
cudaThreadSynchronize();

SomeCudaCall<<<25,34>>>(someParam);
cudaMemcpy(toHere, fromHere, sizeof(int), cudaMemcpyHostToDevice);

【问题讨论】:

  • 我如何知道哪些呼叫被阻塞,哪些不是?我在库描述中没有看到任何“我是阻塞 API 调用”的内容。即在 cudaMemcpy 描述中没有提到阻塞。 (也许我找错地方了?)
  • 我怀疑任何涉及 hostdevice 的函数都会被阻塞,除非它的名称中包含async。除了cudaDeviceSynchronize(),所有其他函数都是非阻塞的

标签: cuda


【解决方案1】:

你的例子是等价的。如果你想要异步执行,你可以使用流或上下文和cudaMemcpyAsync,这样你就可以与复制重叠执行。

【讨论】:

  • cudaMemcpy 是否在其复制操作之前提供阻塞,然后之后?即在复制操作开始之前我是否知道内核已经完成?还是复制操作“结束”时的阻塞表明内核完成和复制完成?
  • 单个流中的操作不会重叠(它们总是串行执行)。因此,在单个流中,memcpy/asyncMemcpy/kernels 将在所有先前的操作(内核或其他 memcpys)完成后启动。
【解决方案2】:

根据 NVIDIA 编程指南:

为了方便主机和设备之间的并发执行,一些函数调用是异步的:在设备完成请求的任务之前,控制权被返回给主机线程。它们是:

  • 内核启动;
  • 两个地址之间的内存复制到同一个设备内存;
  • 64 KB 或更少内存块的从主机到设备的内存复制;
  • 由后缀为 Async 的函数执行的内存拷贝;
  • 内存设置函数调用。

只要您的传输大小大于 64KB,您的示例就是等效的。

【讨论】:

  • 谢谢你,我不明白为什么我的调用似乎没有同步,原来是这个项目:从主机到设备的内存复制 64 KB 的内存块或少;
猜你喜欢
  • 2014-04-20
  • 2012-02-20
  • 2016-07-06
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 2016-07-04
相关资源
最近更新 更多