我需要在每次内核调用后将一个布尔值或整数值从设备复制到主机(我在for循环中调用相同的内核)。也就是说,在每次内核调用之后,我需要将一个整数或一个布尔值发送回主机。这样做的最佳方式是什么?
我应该将值直接写入RAM吗?或者我应该使用cudaMemcpy()?或者还有其他方法吗?每次内核启动后只复制1个整数会减慢我的程序吗?
答案 0 :(得分:4)
让我先回答你的上一个问题:
每次内核启动后只复制1个整数会减慢我的程序吗?
有点 - 是的。发出命令,等待GPU响应等等......在这种情况下,数据量(1 int vs 100 ints)可能并不重要。但是,您仍然可以实现每秒数千次内存传输的速度。最有可能的是,你的内核将比这个单个内存传输慢(否则,在CPU上执行整个任务可能会更好)
最好的方法是什么?
好吧,我建议你自己尝试一下。正如您所说:您可以使用映射固定内存并让内核将值直接存储到RAM中,或使用cudaMemcpy。如果你的内核在发回整数之后还有一些工作要做,那么第一个可能会更好。在这种情况下,可以通过内核的执行来隐藏将其发送到主机的延迟。
如果使用第一种方法,则必须调用cudaThreadsynchronize()
以确保内核结束执行。内核调用是异步的。
您可以使用同步的cudaMemcpyAsync
,但GPU不能运行内核并且并行执行cudaMemcpyAsync
,除非您使用流。
我从来没有尝试过,但如果你的程序在循环执行次数太多时不会崩溃,你可能尝试忽略同步并让它迭代直到在RAM中看到特殊值。在该解决方案中,内存传输可能完全隐藏,您只需在结束时支付开销。但是,您需要以某种方式阻止循环迭代太多次,CUDA事件可能会有所帮助。
答案 1 :(得分:1)
为什么不使用固定内存?如果您的系统支持它 - 请参阅CUDA C编程指南中有关固定内存的部分。
答案 2 :(得分:0)
将数据复制到GPU或从GPU复制数据要比从CPU访问数据慢得多。如果你没有为这个值运行大量的线程,那么这将导致非常慢的性能,不要这样做。
您所描述的内容听起来像是一个串行算法,您的算法需要并行化才能使其值得使用CUDA。如果你不能改写你的算法,成为单个写入多个数据到GPU,多个线程,单个多个数据写回CPU;那么你的算法应该在CPU上完成。
答案 3 :(得分:0)
如果你需要在之前的内核调用中计算的值来启动下一个,那么就会被序列化,你可以选择 cudaMemcpy(dst,src,size = 1,...); < / p>
如果所有内核启动参数都不依赖于先前的启动,那么您可以将每个内核调用的所有结果存储在GPU内存中,然后立即下载所有结果。