⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dynamic-mandel.c

📁 利用并行技术
💻 C
字号:

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <mpi.h>

const int	X_RESN = 800;									// x resolution 
const int	Y_RESN = 800;   								// y resolution 
const int 	proc_num=8;						     			// slave processor number
const int	each=10;										// row numbers to send each time
const int	DATA_TAG=66666;
//const int	RESULT_TAG=77777;
//const int	SOURCE_TAG=88888;
const int	TERMIN_TAG=99999;

typedef struct complextype
{
        float real, imag;
} Compl;

long* draw(int row){
		int i,j;
		Compl z,c;
		long k;
		long *pts=malloc(X_RESN*each*sizeof(long));
		double temp, lengthsq;
		for(j=0;j<each;j++){
			for(i=0; i < X_RESN; i++) {
				z.real = z.imag = 0.0;
				c.real = ((float)i - (float)X_RESN/2)/(float)X_RESN*4;
				c.imag = ((float)(j+row*each) - (float)Y_RESN/2)/(float)Y_RESN*4;
				k=0;
				do  {
						temp = z.real*z.real - z.imag*z.imag +c.real;
						z.imag = 2.0*z.real*z.imag +c.imag;
						z.real = temp;
						lengthsq = z.real*z.real+z.imag*z.imag;
						k++;
				 } while (lengthsq < 10.0 && k < 10000);
				pts[j*X_RESN+i]=k;
			}
		}
	return pts;
}

int main(int argc, char ** argv) 
{   
	int size,rank,i,j,p;
	MPI_Status status;
	MPI_Init(&argc, &argv); 
	MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
	MPI_Comm_size(MPI_COMM_WORLD,&size); 

	// data computing
	if(rank==0){//master assign the row numbers to slaves
		int rows=0;//rows sent
		int count=0;//counter for termination
		for(p=1;p<=proc_num;p++){
			MPI_Send(&rows, 1, MPI_INT, p, DATA_TAG, MPI_COMM_WORLD);
			count++;
			rows++;
		}
		Window		win;                  		          		
		unsigned
		int         width, height,         		         		
	                x, y,   			            		           	 	
	                x_s, y_s,											
	                border_width,       		            		
	                display_width, display_height,  		
	                screen;                   				      		

		char        *window_name = "Mandelbrot Set", *display_name = NULL;
		GC          gc;
		unsigned
		long		valuemask = 0;
		XGCValues	values;
		Display		*display;
		XSizeHints	size_hints;
		Pixmap		bitmap;
		XPoint		points[X_RESN];
		FILE		*fp, *fopen ();
		char		str[100];	
		XSetWindowAttributes attr[1];
	        int i, j, k;
	        Compl	z, c;
	        float	lengthsq, temp;		
		if (  (display = XOpenDisplay (display_name)) == NULL ) {
		   fprintf (stderr, "drawon: cannot connect to X server %s\n",
					XDisplayName (display_name) );
		exit (-1);
		}
		screen = DefaultScreen (display);
		display_width = DisplayWidth (display, screen);
		display_height = DisplayHeight (display, screen);
		width  = X_RESN;
		height = Y_RESN;
		x = 0;	y = 0;	
		border_width = 4;
		win = XCreateSimpleWindow (display, RootWindow (display, screen),
					x, y, width, height, border_width, 
					BlackPixel (display, screen), WhitePixel (display, screen));
		size_hints.flags = USPosition|USSize;
		size_hints.x = x;
		size_hints.y = y;
		size_hints.width = width;
		size_hints.height = height;
		size_hints.min_width = X_RESN;
		size_hints.min_height = Y_RESN;	
		XSetNormalHints (display, win, &size_hints);
		XStoreName(display, win, window_name);
		gc = XCreateGC (display, win, valuemask, &values);
		XSetLineAttributes (display, gc, 1, LineSolid, CapRound, JoinRound);
		attr[0].backing_store = Always;
		attr[0].backing_planes = 1;
		attr[0].backing_pixel = BlackPixel(display, screen);
		XChangeWindowAttributes(display, win, CWBackingStore | CWBackingPlanes | CWBackingPixel, attr);
		XMapWindow (display, win);
		XSync(display, 0);	
		// receive and plot
		long templ;
		do{
			long *pts=malloc(X_RESN*each*sizeof(long));
			MPI_Recv(pts, X_RESN*each, MPI_LONG, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,&status);
			int source=status.MPI_SOURCE;//get slave rank
			if(source==0){//not master
				continue;
			}
			count--; //count decrease
			int rrow=status.MPI_TAG;//current row
			//printf("from slave %d (row %d):\n",source,rrow);
			if(rrow<Y_RESN/each){
				for(j=0;j<each;j++){
				   	for(i=0;i<X_RESN;i++){
						templ=pts[j*X_RESN+i];
						XSetForeground(display,gc,(long) (templ*templ*templ*templ));
						XDrawPoint (display, win, gc, i, j+each*rrow);
						//printf("%d |", templ);
				   	}
					//printf(">>\n");
		   		}
				MPI_Send(&rows, 1, MPI_INT, source, DATA_TAG, MPI_COMM_WORLD);
				count++;
				rows++;
			}else{
				MPI_Send(&rows, 1, MPI_INT, source, TERMIN_TAG, MPI_COMM_WORLD);
			}			
			XFlush (display);
		}while(count>0);
		sleep (1000);
	}
	else {//slave receive row number
		int srow;
		MPI_Recv(&srow, 1, MPI_INT, 0, MPI_ANY_TAG,MPI_COMM_WORLD,&status);
		int source_tag=status.MPI_TAG;
		while(source_tag==DATA_TAG){
			//printf("node %d get %d\n",rank, srow);
			long *pts=malloc(X_RESN*each*sizeof(long));
	  		pts=draw(srow);
			MPI_Send(pts, X_RESN*each, MPI_LONG, 0, srow, MPI_COMM_WORLD);
			MPI_Recv(&srow, 1, MPI_INT, 0, MPI_ANY_TAG,MPI_COMM_WORLD,&status);
			source_tag=status.MPI_TAG;
		}
	}
	// drawing
	MPI_Finalize();	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -