如何跨内核调用将数据保存在快速GPU内存中?
让我们假设,我需要回答100万个查询,每个查询都有大约1.5MB的数据,这些数据可以在调用中重复使用,并且每个查询都有大约8KB的数据。
一种方法是为每个查询启动内核,每次将1.5MB + 8KB的数据复制到共享内存。但是,我花了很多时间来复制1.5MB的数据,这些数据确实可以在查询中持续存在。
另一种方法是“循环”GPU线程(参见https://stackoverflow.com/a/49957384/3738356)。这涉及启动一个内核,立即将1.5MB数据复制到共享内存。然后内核等待请求进入,等待8KB数据出现,然后再进行每次迭代。看起来CUDA似乎不是以这种方式使用的。如果只使用托管内存,并且使用volatile +单调递增计数器进行同步,则仍然无法保证在您阅读时计算答案所需的数据将在GPU上。您可以使用-42之类的虚拟值为内存中的值设置种子值,这些值表示该值尚未进入GPU(通过缓存/托管内存机制),然后忙等待,直到值变为有效。从理论上讲,这应该有效。但是,我有足够的记忆错误,我现在已经放弃了,而且我已经追求....
另一种方法仍然使用回收线程,而是通过cudaMemcpyAsync
,cuda流,cuda事件以及仍有一些易变+单调增加的计数器同步数据。我听说我需要固定每个查询新鲜的8KB数据,以便cudaMemcpyAsync
正常工作。但是,异步副本不会被阻止 - 它的效果是不可观察的。我怀疑有足够的勇气,我也能做到这一点。
然而,以上所有让我觉得“我做错了。” 如何在GPU缓存中保留极其可重复使用的数据,以便可以从一个查询访问到下一个查询?
答案 0 :(得分:1)