我已经使用cudaMalloc在设备上分配了内存并将其传递给内核函数。在内核完成执行之前,是否可以从主机访问该内存?
答案 0 :(得分:2)
在内核仍在执行时,我能想到让memcpy启动的唯一方法是在与内核不同的流中提交异步memcpy。 (如果对内核启动或异步memcpy使用默认API,则NULL流将强制序列化两个操作。)
但由于无法将内核的执行与流同步,因此该代码将受到竞争条件的影响。即复制引擎可能从内核尚未写入的内存中拉出。
提到映射固定内存的人就是这样:如果内核写入映射的固定内存,它会在完成处理时将数据“复制”到主机内存。如果内核不会再次触摸数据,这个习惯用法很好。
答案 1 :(得分:1)
这是可能的,但是不能保证以这种方式检索的内存内容,因为你不知道内核的进展是什么。
您要实现的目标是重叠数据传输和执行。这可以通过使用流来实现。您可以创建多个CUDA流,并在每个流中对内核执行和设备到主机cudaMemcpy进行排队。例如,将填充位置“0”的内核和cudaMemcpy从该位置返回到主机到流0,内核填充位置“1”并将cudaMemcpy从“1”填充到流1中,等等。然后会发生什么呢? GPU将从“0”重复复制并执行“1”。 检查CUDA文档,它记录在某处(在最佳实践指南中,我认为)。
答案 2 :(得分:0)
无论内核是否正在运行,您都无法直接从主机访问GPU内存。
如果您正在讨论在内核完成写入之前将内存复制回主机,则答案取决于设备的计算能力。但是,除了最老的芯片外,所有芯片都可以在内核运行时执行数据传输。
您似乎不太可能想要复制内核仍在更新的内存。您将获得部分完成数据的随机快照。相反,您可能希望在设备上设置两个缓冲区。您可以在GPU工作时复制其中一个缓冲区。
更新
根据您的澄清,我认为您可以获得的最接近的是使用映射的页面锁定主机内存,也称为零拷贝内存。使用此方法,值将在内核写入时复制到主机。没有办法查询内核以查看它执行了多少工作,因此我认为您必须重复扫描内存以获取新写入的值。有关详细信息,请参阅“CUDA编程指南”v4.2中的第3.2.4.3节“映射内存”。
我不建议这样做。除非你有一些非常不寻常的要求,否则可能有更好的方法来完成你的任务。
答案 3 :(得分:0)
启动内核时,它是一个异步(非阻塞)调用。接下来调用cudaMemcpy将阻塞,直到内核完成。
如果您希望将结果用于调试目的,则可以使用cudaDebugging,您可以在其中逐步执行内核并检查内存。
对于小结果检查,您还可以在内核代码中使用printf()。
如果您对该特定结果感兴趣,请仅运行大小为(1,1)的线程块。