c++ - CUDA 默认流和 CUDA_API_PER_THREAD_DEFAULT_STREAM

标签 c++ cuda

The documentation here试图解释如何处理默认流。

给定这样的代码(忽略分配错误):

char *ptr;
char source[1000000];
cudaMalloc((void**)&ptr, 1000000);
cudaMemcpyAsync(ptr, source, 1000000, cudaMemcpyHostToDevice);
myKernel<<<1000, 1000>>>(ptr);

是否存在 myKernelcudaMemcpyAsync 完成复制之前启动的风险?我认为“否”,因为这是文档中所述的“旧版默认流”。

但是,如果我使用 CUDA_API_PER_THREAD_DEFAULT_STREAM 进行编译,会发生什么情况? “每线程默认流”的文本说:

The per-thread default stream is an implicit stream local to both the thread and the CUcontext, and which does not synchronize with other streams (just like explcitly created streams). The per-thread default stream is not a non-blocking stream and will synchronize with the legacy default stream if both are used in a program.

我认为这也可以,因为 cudaMemcpyAsyncmyKernel 都有效地使用了 CU_STREAM_PER_THREAD;我说得对吗?


我问的原因是我在内核中有一个非常奇怪的间歇性 CUDA 错误 77,我只能用 cudaMemcpyAsync 在调用 myKernel 之前未完成来解释>,这意味着我不理解文档。不过,真正的代码过于复杂且过于专有,无法制作 MCVE。

最佳答案

Is there a risk that myKernel will start before cudaMemcpyAsync finishes copying? I think "No" because this is a "Legacy default stream" as described in the documentation.

不,这不可能发生,因为正如您所注意到的,旧版默认流(流 0)在所有情况下都是阻塞的。

However, if I compile with CUDA_API_PER_THREAD_DEFAULT_STREAM what happens?

几乎没有任何变化。每线程默认流不阻塞,因此其他流和使用其默认流的其他线程可以在上下文中并发运行。然而,这两个操作仍然在同一个流中并且相对于彼此是顺序的。如果 source 是一个不可分页的内存分配,这两个操作之间可能发生重叠的唯一方法是允许传输和内核执行之间发生重叠。否则,由于流的顺序属性和主机源内存施加的限制,它们将按顺序运行。

如果您怀疑操作的意外重叠确实存在问题,您应该能够通过分析来确认这一点。

关于c++ - CUDA 默认流和 CUDA_API_PER_THREAD_DEFAULT_STREAM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51418001/

相关文章:

C++ SFML 数组错误 : Access violation reading location 0xC0000005

c++ - 使用模板参数作为模板参数类型

c++ - 防止使用 ImpersonateNamedPipeClient()

parallel-processing - 处理 CUDA 中的大型 switch 语句

CUDA - 使用(未对齐的)子图像(用于纹理绑定(bind)、NPP...)时有任何问题吗?

CUDA cudaDeviceProp 构建 deviceQuery 示例时没有成员错误

c++ - 在 find() 中提供 bool 值是不是不好的风格?

c++ - 在动态数组中存储指针或指针数组

c++ - 如何将类的非静态成员函数传递给 CUDA 内核函数(__global__ 函数)

CUDA 5.5 中的 cudaMemcpy3D 设置问题