我有一个多次调用的CUDA内核(100万不是限制)。我们是否再次启动内核取决于flag(result_found),我们的内核返回。消除内核调用之间的cudaMemcpy
for(int i = 0; i < 1000000 /* for example */; ++i) {
kernel<<<blocks, threads>>>(/*...*/, dev_result_found);
cudaMemcpy(&result_found, dev_result_found, sizeof(bool), cudaMemcpyDeviceToHost);
if(result_found) {
break;
}
}
探查说cudaMemcpy花费更多的时间来执行,不是实际的内核调用(cudaMemcpy:〜88US,cudaLaunch:〜17us)。
所以,问题是:
1)有什么办法避免调用cudaMemcpy这里?
2)为什么它毕竟如此缓慢?将参数传递给内核(cudaSetupArgument)看起来非常快(〜0.8 us),而获得结果很慢。如果我删除cudaMemcpy,我的程序会更快完成,所以我认为这不是因为同步问题。
还有其他方法(例如零拷贝),但是在读取'result_found'的值之前,它们仍然依赖于同步(迫使内核完成)。你的分析方法可能有缺陷。 'cudaLaunch'(运行时API调用)的持续时间与内核的持续时间不同。实际上,您应该查看Profiler中内核的持续时间(取决于您使用的是哪个分析器)。所以,这里的答案很可能就是你误解了剖析器数据。但是如果没有更多关于你如何分析的信息,我不能一概而论。 –