使用 MPI 并行化 Mandelbrot

问题描述 投票:0回答:1

我正在尝试并行化 Mandelbrot。 正确的输出应该在 1.510659 左右。但是我没有正确理解。

** 项目:Mandelbrot 区域 ** ** 目的:计算 Mandelbrot 集面积的程序。 ** 正确答案应约为 1.510659。 ** ** 用法:程序无需输入即可运行...只需运行可执行文件 ** 减少 numoutside。

这是我的并行化代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>

#define NPOINTS 1000
#define MAXITER 1000
int P = 1;
struct d_complex
{
  double r;
  double i;
};

int testpoint(struct d_complex);

struct d_complex c;
struct d_complex cPart;
int numoutside = 1;

int main()
{
  int i, j, row;
    int res;
  double area, error, eps = 1.0e-5;
  int myrank, mysize;
  double stsec, ensec, commtime, maxcommtime;
  MPI_Status status;
  MPI_Init(NULL, NULL);
  MPI_Comm_size(MPI_COMM_WORLD, &mysize);
  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  stsec = MPI_Wtime();
  //   Loop over grid of points in the complex plane which contains the Mandelbrot set,
  //   testing each point to see whether it is inside or outside the set.
  /*for (i = 0; i < NPOINTS; i ++)
  {
    for (j = 0; j < NPOINTS ; j++)
    {
      c.r = -2.0 + 2.5 * (double)(i) / (double)(NPOINTS) + eps;
      c.i = 1.125 * (double)(j) / (double)(NPOINTS) + eps;
      testpoint(c);
    }
  }*/

  if (myrank == 0)
  {
  

    /* Begin User Program  - the master */
    //*
    int outsum, nb_pixel = NPOINTS*NPOINTS ;
    for (i = 0; i < nb_pixel; i++)
    {
      MPI_Recv(&res, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
      // printf("Slave id %d has send : %d \n", status.MPI_SOURCE, data[2]);
      // printf("%d: [%d,%d] -> [%d,%d] = %d\n", status.MPI_SOURCE, data[0], data[1], data[0] + MAXX, data[1] + MAXY, data[2]);
      res += numoutside;
    }
     area = 2.0 * 2.5 * 1.125 * (double)(NPOINTS * NPOINTS - res) / (double)(NPOINTS * NPOINTS);
   error = area / (double)NPOINTS;
    printf("Area of Mandlebrot set = %12.8f +/- %12.8f\n", area, error);
    printf("Finish.\n");
  }
  else
  {
   
    for (i = myrank; i < NPOINTS; i+=mysize)
    {
      for (j = 0; j < NPOINTS; j++)
      {
        c.r = -2.0 + 2.5 * (double)(i) / (double)(NPOINTS) + eps;
        c.i = 1.125 * (double)(j) / (double)(NPOINTS) + eps;
        res=testpoint(c);
         MPI_Send(&res, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
      }
    }
  }

  // Calculate area of set and error estimate and output the results

  MPI_Finalize();
  ensec = MPI_Wtime();
  commtime = ensec - stsec;
  // area = 2.0 * 2.5 * 1.125 * (double)(NPOINTS * NPOINTS - numoutside) / (double)(NPOINTS * NPOINTS);
  // error = area / (double)NPOINTS;
  printf("Area of Mandlebrot set = %12.8f +/- %12.8f\n", area, error);

  if (myrank == 0)
  {
    printf("%.3f\n", commtime);
  }
}

int testpoint(struct d_complex c)
{

  // Does the iteration z=z*z+c, until |z| > 2 when point is known to be outside set
  // If loop count reaches MAXITER, point is considered to be inside the set

  struct d_complex z;
  int iter;
  double temp;

  z = c;
  for (iter = 0; iter < MAXITER; iter++)
  {
    temp = (z.r * z.r) - (z.i * z.i) + c.r;
    z.i = z.r * z.i * 2 + c.i;
    z.r = temp;
    if ((z.r * z.r + z.i * z.i) > 4.0)
    {
      // MPI_Send( &numoutside, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
      return numoutside;
      break;
    }
  }
  return 0;
}

当使用 NPOINTS 运行代码时,期望得到大约 1.510659:1000,2000 和 2,4,处理器。

c parallel-processing mpi message-passing mandelbrot
1个回答
0
投票

我不知道 MPI,但我有一个使用线程的 mandelbrot 的 win32 实现。请参阅 https://github.com/alexsokolek2/mandelbrot,特别是 mandelbrot/mandelbrot.cpp。寻找CreateThread()。此代码将图形工作负载划分为 1 到 64 个线程。

© www.soinside.com 2019 - 2024. All rights reserved.