问题描述
在通过OpenMP并行化C ++代码之后,我现在正在考虑使用GPU(Radeon Pro Vega II)来加速我的代码的特定部分。作为OpenCL的新手,我目前正在寻找可以向我展示如何实现多核cpu-GPU交互的示例。
这是我想要实现的目标。假设有一个固定的短长度数组,例如{1,2,3,4,5},作为练习,您想计算该数组的所有可能的“右移”,即
{5,1,4}
{4,5,3}
{3,2}
{2,1}
{1,5}
。
相对的OpenCL代码非常简单。
现在,假设您的cpu有许多核,例如56,每个核都有一个不同的起始阵列,并且每个cpu核在任何随机的时间可能会要求GPU计算自己阵列的右移。该内核(例如内核21)应将其自己的阵列复制到GPU内存中,运行内核,然后等待结果。我的问题是“在执行此操作期间,其他cpu内核可以提交类似的请求,而不必等待内核21提交的任务完成吗?”
此外,内核21是否可以在等待GPU任务完成的同时并行执行另一任务?
您是否想建议一些例子看看?
谢谢!
解决方法
GPU与内核调用和(PCIe-)内存传输队列一起工作。在此队列中,它可以同时处理非阻塞内存传输和一个内核,但不能同时处理两个连续的内核。您可以执行多个队列(每个CPU内核一个队列),然后可以并行执行来自不同队列的内核,前提是每个内核仅占用GPU资源的一小部分。当队列在GPU上执行时,CPU内核可以执行其他任务,并且使用命令queue.finish()
,CPU将等待直到GPU完成。
但是,让多个CPU将任务发送到单个GPU是不好的做法,并且在使代码过于复杂的同时不会给您带来任何性能优势。每个小的PCIe内存传输都具有较大的等待时间开销,而不能充分使GPU饱和的小内核则具有较差的性能。 多CPU方法仅在每个CPU将任务发送到其专用GPU时才有用,即使在单个GPU的VRAM不足或要比单个GPU拥有更多并行吞吐量的情况下,我也建议这样做。允许。
更好的策略是为GPU提供单个CPU内核,并且-如果在CPU端要进行某些处理,则只能跨多个CPU内核并行化。通过将小数据包组合到单个大PCIe内存传输和大内核中,您将使硬件饱和并获得最佳性能。
有关GPU上并行化如何工作的更多详细信息,请参见https://stackoverflow.com/a/61652001/9178992