#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
#include <time.h>
#include <math.h>
#include <sys/time.h>
#define NUM 512
int id,nproc;
int colorbuf[NUM * NUM];
double cx0,cx1,cy0,cy1;
int n;
double dx,dy;
int p_n;
struct timeval startTime, endTime;
double timeused_p;
void draw()
{
int i = 0;
int j = 0;
int k = 0;
FILE *fp = fopen("001.ppm", "wb");
fprintf(fp, "P6\n# Mandelbrot, xmin=%d, xmax=%d, ymin=%d, ymax=%d, maxiter=%d\n%d\n%d\n%d\n",-2,2,-2,2,NUM,NUM,NUM,(NUM < 256 ? 256 : NUM));
for (j=0;j<n;j++)
{
for(i=0;i<n;i++)
{
int temp=colorbuf[j*n+i];
if (temp == NUM)
{
const unsigned char black[] = {0,0,0};
fwrite(black, 3, 1, fp);
}
else
{
unsigned char color[3];
color[0] = temp >> 8;
color[1] = temp & 255;
color[2] = temp >> 8;
fwrite(color, 3, 1, fp);
};
}
}
fclose(fp);
}
int compColor(double creal, double cimage)
{
double real, image;
double nreal, nimage;
double tmp;
int i;
real = creal;
image = cimage;
for (i = 0; i < NUM; i++)
{
tmp = real*real + image*image;
if (tmp >= 4.0) return i;
nreal = real*real - image*image + creal;
nimage = real*image*2.0 + cimage;
real = nreal;
image = nimage;
}
return NUM;
}
void colorCalculate()
{
dx=(cx1-cx0)/n;
dy=(cy1-cy0)/n;
int locN=n/nproc;
int i,j,k;
double cx,cy;
for (j=id*locN;j<=id*locN+locN-1;j++)
{
cy= cy0+j*dy;
for(i=0;i<n;i++)
{
cx=cx0+i*dx;
colorbuf[j*n+i]=compColor(cx, cy);
}
}
}
int main()
{
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&id);//id存放进程的标识
MPI_Comm_size(MPI_COMM_WORLD,&nproc);//nproc存放总进程数
if(id==0)
{
gettimeofday(&startTime, NULL);
cx0=-2;
cx1=2;
cy0=-2;
cy1=2;
n=NUM;
}
MPI_Bcast(&cx0, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&cx1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&cy0, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&cy1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
colorCalculate();
int locN=n/nproc;
if(id!=0){
MPI_Gather(&colorbuf, locN*n, MPI_INT, &colorbuf[id*locN*n], locN*n, MPI_INT, 0, MPI_COMM_WORLD);
}
if(id==0){
gettimeofday(&endTime, NULL);
timeused_p = 1000000 * (endTime.tv_sec - startTime.tv_sec) + endTime.tv_usec - startTime.tv_usec;
timeused_p /= 1000;
printf("静态调度运行时间 : %f ms\n", timeused_p);
draw();
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
这是使用统计模式实现mandelbrot集的C + mpi代码。这是run命令。我的环境是ubuntu 14.04。
这不正常。似乎只有一半的图像。我真的不知道出了什么问题。 抱歉,我们有很长的转储代码。 有人可以帮忙吗?
答案 0 :(得分:0)
我认为你有拼写错误,看看这些行
cx0=-2;
cx1=2;
cy1=-2; // <- should be cy0
cy1=2; //
请记住cy0
被定义为全局变量,所以它的默认值是0.0,因此你得到了一半的图像。
为什么要将数据写入文件为6字节序列。根据参考https://en.wikipedia.org/wiki/Netpbm_format
PPM每像素使用24位:红色为8位,绿色为8位,蓝色为8位
所以你应该改变这些行
const unsigned char black[] = {0,0,0,0,0,0};
fwrite(black, 6, 1, fp);
到
const unsigned char black[] = {0,0,0};
fwrite(black, 3, 1, fp);
和
unsigned char color[6];
color[0] = temp >> 8;
color[1] = temp & 255;
color[2] = temp >> 8;
color[3] = temp & 255;
color[4] = temp >> 8;
color[5] = temp & 255;
fwrite(color, 6, 1, fp);
到
unsigned char color[3];
color[0] = red;
color[1] = green;
color[2] = blue;
fwrite(color, 3, 1, fp);
值红色,绿色,蓝色取决于temp
值(0-512),因此您应将此值缩放到0-255范围内。
答案 1 :(得分:0)
所有等级必须调用MPI_Gather()
,并且参数的顺序正确。由于colorbuf
用作发送和接收缓冲区,因此必须使用MPI_IN_PLACE
。
由于数据足够小,非根等级不会挂起,但colorbuf
未在根等级上汇编,因此结果不正确。
作为一种风格问题,您可以考虑删除全局变量,并将参数添加到子例程中。