Multithreading 如何在n个线程上均匀分配n个对象的所有对测试的工作?

Multithreading 如何在n个线程上均匀分配n个对象的所有对测试的工作?,multithreading,algorithm,parallel-processing,Multithreading,Algorithm,Parallel Processing,一组n对象中所有可能(无序)对上的典型单线程循环如下所示: for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) ProcessPair(i, j); 但这并不能在线程之间均匀地分配工作。第一个线程将处理n-1对,而最后一个线程将不处理任何对 是否有一种简单的方法将n(n-1)/2对进行分区,以便每个线程处理相同数量的对(±1),并且可以仅根据其threadIndex和n确定应该处理哪些对 这

一组
n
对象中所有可能(无序)对上的典型单线程循环如下所示:

for (int i = 0; i < n; i++)
    for (int j = i + 1; j < n; j++)
        ProcessPair(i, j);
但这并不能在线程之间均匀地分配工作。第一个线程将处理
n-1
对,而最后一个线程将不处理任何对

是否有一种简单的方法将
n(n-1)/2对
进行分区,以便每个线程处理相同数量的对(±1),并且可以仅根据其
threadIndex
n
确定应该处理哪些对


这个有趣的问题是在我在GPU上玩物理游戏并开始实现蛮力全对碰撞检测时出现的(我知道,我应该使用宽相位算法)。我认为这可能是关键,但我不能把所有的部分都放在一起。

我对它进行了一些研究,找到了一个似乎正确的解决方案。我没有证据证明它是有效的,也没有证据证明它是平衡的,但就我所知,它在逻辑上是合理的

简言之: 如果你的指数是偶数,检查所有比你小的偶数指数和比你大的奇数指数。如果你在一个奇数指数,检查所有比你小的奇数指数和比你大的偶数指数


很容易看出,每个线程最多会与N/2个其他线程进行比较,因为我们将在第2步中查看整个列表。

使用单独的计数器变量并调用
ProcessPair(dispatchCounter%numberOfThreads,i,j)
?@zneak我不确定这有什么帮助?目标是让
ProcessPair(i,j)
为每个可能的集合
{i,j}
调用一次,其中
i≠j
。一种通用的方法是在集合
{i,j}
和数字范围
[1..n(n-1)/2]
之间找到一个双射,一个“明显的”双射是
f(i,j)=j-i-1+n(n-1)/2-(n-i)(n-i-1)/2
(只是从上到下,从左到右对矩阵中的单元格进行编号):P不幸的是,反转有点尴尬,没有Ehsan的解决方案那么优雅我已经通过实验证实了它的有效性。非常酷的算法!明亮的我也通过一张图片证明了这一点。所有对只处理一次,当N为偶数时,线程处理N/2对,另一半处理N/2-1对。
for (int j = threadIndex + 1; j < n; j++)
    ProcessPair(threadIndex, j);