嵌套循环除法

时间:2016-02-15 22:41:12

标签: parallel-processing mpi

我需要均匀地划分嵌套循环。现在,如果ij大致均匀

,我知道如何执行此操作
 mystart = (n / numproc) * myid;
  if (n % numproc > myid){
    mystart += myid;
    myend = mystart + (n / numproc) + 1;
  }else{
    mystart += n % numproc;
    myend = mystart + (n / numproc);

  for(i=mystart; i<myend; ++i)

但是我需要计算每个粒子之间的距离,所以循环看起来像这样:

* * * * * * * * * * * * * 
* * * * * * * * * * * * *
* * * * * * * * * * * *
* * * * * * * * * * *
* * * * * * * * * *
* * * * * * * * *
* * * * * * * *
* * * * * * *
* * * * * *
* * * * *
* * * *
* * * 
* * 
* 

但更大。每个*都是一个操作。因此,如果我使用之前的算法,那么最后的流程将完成他们的工作,而第一个流程甚至不会在那里,这是无效的。 是否有某种算法可以与MPI一起使用?

我认为可能有办法将每个迭代分配给下一个进程,如下所示: (i - 迭代,p - 过程(满分3))

 i1 -> p1, i2 -> p2, i3 -> p3, i4 -> p1, i5 -> p2 (and so on)

但我不确定它是否有效以及如何实现这一点。 如果你们有一些想法,那么我很乐意看到他们在MPI中使用的例子。

编辑: @Zulan用代码解释会更容易。我的代码在框内生成随机粒子(x,y,z)。所有与这些粒子相邻的信息只有处理秩== 0才知道。我必须使用MPI实现方法(链接到下面的代码)以使这些计算更快。

我必须找到一对距离最小的一对粒子(所以n *(n-1))ops)删除那对,我必须这样做NumberofParticlestoRemove次。这个方法是我主要关注的问题,因为我不确定如何划分循环。

以下是源代码:http://pastebin.com/XxBGd50j 这是我的尝试(未完成):http://pastebin.com/Yd8DwwfX

在计算出距离之后,我想我会使用MPI_Reduce来获得最小距离,但我不知道如何将这对位置与最小距离值联系起来(有三个向量x,y,z,所以如果最近的距离将在粒子ex.5和10之间,它是x [5],y [5],z [5] .x [10],y [10],z [10],所以即使它我能够提取最小距离我不知道如何保存数字5和10,以后来消除那些粒子。我说消除但我必须从那对完全定位的新粒子中创建一个新粒子他们的中间人(Helper中的功能)。

1 个答案:

答案 0 :(得分:2)

你正在从一个非常天真的算法的算法方面接近这个。对于可扩展的算法,您永远不希望进行O(n^2)操作。

让我们考虑一下数据如何分发数据? 这是3D域分解的情况。为简单起见,我正在编写一些数字。您将空间划分为100 * 100 * 100个单元格。然后,您有1000个MPI进程,每个进程被分配10 * 10 * 10个单元块。每个MPI等级将具有其自身细胞的粒子加上每个方向上的一个晕圈,添加10 * 10 * 6 + 10 * 12 + 8个细胞 1 2

您如何计算最小距离?每个等级在本地为其自身细胞内的粒子计算它并且它是晕。最小距离是所有局部最小距离(MPI_Reduce)的最小值。

为什么这是正确的?只有当最小距离小于单元格的边缘时,这才是正确的。您可以通过选择单元的大小来保证,即使使用理想的包装,最小距离也会小于单元宽度。然后它将始终小于单元格宽度。

好消息,这是一个known problem,您无需在本地进行二次操作。

现在有趣的问题是:如果我的粒子分布不均匀怎么办?然后你会得到负载不平衡:某些等级比其他等级有更多工作要做。这开辟了整个研究领域。您可以通过向每个等级分发不同数量的单元格来在常规网格上进行负载平衡。或者你甚至可以选择非结构化/自适应网格。有许多论文和软件库可以帮助你。

现在这是一个比直接问题的答案更复杂的答案。当然,您可以非常轻松地并行化蛮力算法 - 这对于低效算法来说非常常见。只要天真地计算新等级上的每一行,给定足够的粒子,余额将渐近完美。

for (particle_a_index = my_rank; particle_a_index < num_particles; particle_a_index += num_procs) {
    for (particle_b_index = particle_a_index + 1; particle_b_index < num_particles; particle_b_index++) {
        ...

但是,不要这样做,更好地实现有效的串行算法。

1 除了边界

2 你实际上只需要一半的光环来解决你的具体问题。