我有一个 OpenCL 内核,它计算系统中其他粒子对粒子施加的总力,然后是另一个集成粒子位置/速度的内核。我想在多个 GPU 上并行化这些内核,基本上为每个 GPU 分配一定数量的粒子。但是,我必须多次运行这个内核,并且每个 GPU 的结果都会在每个 GPU 上使用。让我进一步解释一下:
假设您在 GPU 0 上有粒子 0,在 GPU 1 上有粒子 1。粒子 0 上的力发生了变化,粒子 1 上的力也发生了变化,然后积分器相应地改变了它们的位置和速度。然后,这些新位置需要放置在每个 GPU 上(两个 GPU 都需要知道粒子 0 和粒子 1 都在哪里),并且这些新位置用于计算下一步中每个粒子上的力,由积分器,其结果用于计算力等。本质上,在力计算滚动时,所有缓冲区都需要包含相同的信息。
所以,问题是:考虑到每个 GPU 都有不同的缓冲区,跨 GPU 同步缓冲区的最佳方法是什么?根据我的最后一个问题,如果我想保持并行性,它们就不能有一个共享缓冲区(不过,如果有办法创建一个共享缓冲区并仍然保留多个 GPU,我完全赞成)。我怀疑复制每个步骤的结果会导致比跨 GPU 并行化算法更慢的速度。
我确实找到了这个线程,但答案不是很明确,仅适用于所有 GPU 的单个缓冲区。我想知道,特别是对于 Nvidia GPU(更具体地说,是 Tesla M2090)。
编辑:实际上,根据Khronos 论坛上的这个帖子,OpenCL 工作组的一位代表表示,共享上下文上的单个缓冲区确实会分布在多个 GPU 上,每个 GPU 都确保它在内存中拥有最新信息. 但是,我在 Nvidia GPU 上没有看到这种行为。当我watch -n .5 nvidia-smi
在后台运行程序时使用时,我看到一个 GPU 的内存使用量上升了一段时间,然后在另一个 GPU 的内存使用量上升时下降。有没有人可以指出我正确的方向?也许这只是他们的实施?