首页 文章

OpenCL - 多GPU缓冲同步

提问于
浏览
3

我有一个OpenCL内核,它计算系统中其他粒子施加的粒子上的总力,然后是另一个整合粒子位置/速度的粒子 . 我想在多个GPU上并行化这些内核,基本上为每个GPU分配一些粒子 . 但是,我必须多次运行此内核,并且每个GPU都会使用每个GPU的结果 . 让我再解释一下:

假设你在GPU 0上有粒子0,在GPU 1上有粒子1.粒子0上的力被改变,粒子1上的力也是如此,然后它们的位置和速度由积分器相应地改变 . 然后,需要将这些新位置放置在每个GPU上(两个GPU都需要知道粒子0和粒子1都在哪里)并且这些新位置用于计算下一步中每个粒子上的力,这是由积分器,其结果用于计算力等,等等. Essentially, all the buffers need to contain the same information by the time the force calculations roll around.

那么,问题是: What is the best way to synchronize buffers across GPUs, given that each GPU has a different buffer ?如果我想保持并行性,它们不能有一个共享缓冲区,但是,如果有一种方法可以创建共享缓冲区并且仍然保留多个GPU,那么我需要在GPU中并行化算法 .

我找到了this thread,但答案不是很明确,只适用于所有GPU的单个缓冲区 . 我想特别了解Nvidia GPU(更具体地说,特斯拉M2090) .

EDIT: 实际上,根据this thread on the Khronos forums,OpenCL工作组的代表说,共享上下文中的单个缓冲区确实会分布在多个GPU上,每个GPU确保它在内存中具有最新信息 . 但是,我没有在Nvidia GPU上看到这种行为;当我的程序在后台运行时使用 watch -n .5 nvidia-smi 时,我看到一个GPU 's memory usage go up for a while, and then go down while another GPU'的内存使用率上升 . 有没有人可以指出我正确的方向?也许只是他们的实施?

1 回答

  • 4

    听起来你遇到了实施问题 .

    SIGGRAPH有一个很棒的演示文稿,它展示了一些利用多个GPU和共享内存的不同方法 . 幻灯片是here .

    我想,在您当前的设置中,您有一个包含多个具有多个命令队列的设备的上下文 . 对于你正在做的事情,这可能是正确的方法 .

    OpenCL 1.2 specification的附录A说:

    OpenCL内存对象[...]是使用上下文创建的,可以在使用相同上下文创建的多个命令队列之间共享 .

    进一步:

    应用程序需要在主机处理器上的线程之间实现适当的同步,以确保在多个线程中的多个命令队列时,以正确的顺序发生对共享对象状态的更改[...]更改共享对象的状态 .

    因此,在我看来,计算粒子位置和速度的内核需要依赖于计算粒子间力的内核 . 听起来你已经知道了 .

    根据你的问题更多地说明问题:

    考虑到每个GPU有不同的缓冲区,在GPU之间同步缓冲区的最佳方法是什么?

    ...我认为答案是"don't have the buffers be separate."通过让 cl_mem 对象来自同一个上下文,在两个设备之间使用相同的 cl_mem 对象 .

    至于数据实际存在的位置......正如你所指出的那样,这是实现定义的(至少从规范中可以看出) . 您可能不应该担心数据的存在位置,只需从两个命令队列中访问数据 .

    我意识到这可能会产生一些严重的性能问题 . 实现可能会发展并变得更好,所以如果你现在根据规范编写代码,它将来可能会运行得更好 .

    为了获得更好(或最不同)的缓冲区共享行为,您可以尝试的另一件事是将粒子数据设为 Map .

    如果有任何帮助,我们的设置(一堆具有双C2070的节点)似乎可以相当优化地共享缓冲区 . 有时,数据仅保留在一个设备上,有时可能在两个地方都存在数据 .

    总而言之,我认为这里的答案是 do it in the best way the spec provides and hope for the best in terms of implementation.

    我希望我能提供帮助,

    瑞安

相关问题