很抱歉,如果这很明显,但我现在正在学习c ++和Cuda,并想知道这是否可行,所以我可以更多地关注相关部分。
基本上我的问题是高度可并行化的,事实上我现在正在多个服务器上运行它。我的程序获得一个工作项(非常小的列表)并在其上运行循环并做出3个决定之一:
这曾经是一个递归,但我使每个部分都独立,虽然我更长时间被一个cpu绑定但是它的负面影响是有很多消息来回传递。我从很高的层面理解CUDA如何工作以及如何向其提交工作,但CUDA是否可以管理设备本身的队列?
我当前的思维过程是管理c ++主机上的队列,然后将处理发送到设备,之后结果返回给主机并发送回设备(依此类推)。我认为这可行,但我想看看是否有可能在CUDA内存上拥有队列并且内核可以正常工作并直接向它发送工作。
使用CUDA是否可以这样,或者有更好的方法吗?
答案 0 :(得分:1)
我认为您要问的是,您是否可以在设备上保留中间结果。答案是肯定的。换句话说,您应该只需要将新工作项复制到设备,并且只需从设备复制完成的项目。仍未确定的工作项可以在内核调用之间保留在设备上。
你可能想要研究一下CUDA Thrust。 Thrust具有高效的转换算法,可以与自定义逻辑相结合(在Thrust手册中搜索“内核融合”。)听起来好像您的处理可以被认为是转换,您可以在其中获取工作项的向量并创建两个新的向量,一个要保留的项目和一个仍未确定的项目。
主机是否知道(或可以监控)设备上的内存?我关注的是如何了解和处理开始超过GPU板载内存的数据。
可以从内核中分配和释放内存,但它可能不会非常有效。相反,通过运行CUDA调用(例如cudaMalloc()
和cudaFree()
来管理内存,或者,如果您正在使用Thrust,则在内核调用之间创建或调整向量。
通过这种“手动”内存管理,您可以跟踪cudaMemGetInfo()
使用的内存量。
由于您将完成的工作项复制回主机,因此您将知道设备上剩余的工作项数,以及内核调用可能需要的最大内存量。
也许一个好的策略是为每个变换交换源和目标向量。举一个简单的例子,假设您有一组要在多个步骤中过滤的工作项。您创建矢量A并用工作项填充它。然后创建相同大小的矢量B并将其留空。过滤后,A中的部分工作项已移至B,您有计数。现在再次运行过滤器,这次以B为源,A为目标。