CUDA 流不重叠
Posted
技术标签:
【中文标题】CUDA 流不重叠【英文标题】:CUDA streams not overlapping 【发布时间】:2011-08-29 13:10:07 【问题描述】:我有一些与代码非常相似的东西:
int k, no_streams = 4;
cudaStream_t stream[no_streams];
for(k = 0; k < no_streams; k++) cudaStreamCreate(&stream[k]);
cudaMalloc(&g_in, size1*no_streams);
cudaMalloc(&g_out, size2*no_streams);
for (k = 0; k < no_streams; k++)
cudaMemcpyAsync(g_in+k*size1/sizeof(float), h_ptr_in[k], size1, cudaMemcpyHostToDevice, stream[k]);
for (k = 0; k < no_streams; k++)
mykernel<<<dimGrid, dimBlock, 0, stream[k]>>>(g_in+k*size1/sizeof(float), g_out+k*size2/sizeof(float));
for (k = 0; k < no_streams; k++)
cudaMemcpyAsync(h_ptr_out[k], g_out+k*size2/sizeof(float), size2, cudaMemcpyDeviceToHost, stream[k]);
cudaThreadSynchronize();
cudaFree(g_in);
cudaFree(g_out);
'h_ptr_in' 和 'h_ptr_out' 是用 cudaMallocHost 分配的指针数组(没有标志)。
问题是流不重叠。 在可视化分析器中,我可以看到第一个流中的内核执行与第二个流中的副本 (H2D) 重叠,但没有其他重叠。
我可能没有资源来运行 2 个内核(我想我有),但至少内核执行和复制应该是重叠的,对吧? 如果我将所有 3 个(复制 H2D、内核执行、复制 D2H)放在同一个 for 循环中,它们都不会重叠......
请帮忙,这是什么原因造成的?
我正在跑步:
Ubuntu 10.04 x64
设备:“GeForce GTX 460” (CUDA 驱动程序版本:3.20, CUDA 运行时版本:3.20, CUDA 能力主要/次要版本号:2.1, 并发复制和执行:是, 并发内核执行:是)
【问题讨论】:
CUDA 中的分析机制在某些情况下会导致流中的序列化。您不能使用分析器来判断异步 API 操作的重叠。 谢谢。有没有其他方法可以确定重叠是否正确?从时间来看,它似乎不是...... 【参考方案1】:根据 NVIDIA 论坛上的this post,分析器将序列化流式传输以获得准确的时序数据。如果您认为您的时间错了,请确保您使用的是 CUDA 事件...
我最近一直在尝试流式传输,我发现 SDK 中的 "simpleMultiCopy" 示例真的很有帮助,尤其是在适当的逻辑和同步方面。
【讨论】:
【参考方案2】:如果您想看到内核与内核(并发内核)重叠,您需要使用 CUDA 5.0 Toolkit 附带的 CUDA Visual profiler 5.0。我认为以前的分析器无法做到这一点。它还应该显示内核和 memcpy 重叠。
【讨论】:
真的可以直接用 Visual Profiler 5.0 观察流重叠吗?如果是这样,怎么做?我目前正在使用命令行分析器并将生成的 .csv 文件导入分析器,请参阅NVIDIA post on overlapping streams。以上是关于CUDA 流不重叠的主要内容,如果未能解决你的问题,请参考以下文章
GPUNvidia CUDA 编程中级教程——数据复制与计算的重叠
GPUNvidia CUDA 编程中级教程——数据复制与计算的重叠
GPUNvidia CUDA 编程中级教程——数据复制与计算的重叠