📄 mandelbrot_master.c
字号:
/*
* Mandlebrot Sets
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "pvm3.h"
#define X_RESN 800 /* x resolution */
#define Y_RESN 800 /* y resolution */
//define MAX_SLAVES 20
#define MAX_ITER 100
#define LINES_ASSIGNED_PER_TIME 100 /* assign 100 lines a time */
#define SLAVENAME "mandelbrot_slave" /* name of slave file */
#define ENCODING PvmDataDefault
#define DATA_TAG 0
#define TERMINATOR_TAG 1
//define TAG_ANY -1
//define PROC_ANY -1
//int nhost, *stid; /* num of the hosts; array to place slaves' id */
//int display_width = X_RESN;
//int display_height = Y_RESN;
Window win; /* initialization for a window */
Display *display;
GC gc;
Colormap cmap;
unsigned int screen; /* which screen */
//int spawnSlave();
//void killSlaves(int nSlave);
int assignRows(int slaveTid,int startRow);
//int recvResults(int slaveTid, int tag, int *startRow, int *nRows, int result[]);
void drawPixels(int result[], int startRow, int nRows);
void initDisplay(); /*init X-Windows*/
/************************************************************/
void main ()
{
/* init variable */
int i;
/* record time */
time_t startTime, endTime;
int usedTime;
startTime = time(NULL);
printf("Start at %ld.\n", startTime);
int mytid;
if ((mytid = pvm_mytid()) < 0) {
exit(1);
}
printf("I'm t%x\n", mytid);
/* spawn slaves */
int nSlave, n;
struct pvmhostinfo *hosts[20];
//int nhost, narch, i, nSlave;
//struct pvmhostinfo *hostp[MAX_SLAVES];
///* get the state of the pvm, also get num of machines */
if (pvm_config(&nSlave,&n,hosts) < 0)
{
printf("PVM config error!\n");
return 0;
}
//printf("There are %d machines!\n", nhost);
//if(nhost<=0)
//{
//return 0;
//}
/* fork slaves, total num = nhost */
//nSlave = nhost;
int *stid = new int[nSlave];/* array to put slaves' id(s) */
if (pvm_spawn(SLAVENAME, (char**)0, 0, "", nSlave, stid) < 0)
{
printf("Failed to spawnSlave! Program will exit now.\n");
pvm_exit();
exit(-1);
}
printf("Spawned %d slaves. They are: ", nSlave);
for(i=0; i<nSlave; i++)
{
printf(" %x\t", stid[i]);
}
printf("\n");
//return nSlave;
//nSlave = spawnSlave();
/*if(nSlave==0)
{
printf("Failed to spawnSlave! Program will exit now.\n");
pvm_exit();
exit(-1);
}*/
/* at first send job to each slave, to make all slaves busy */
int curRow = 0;
int Count = 0; /* record row number that haven't returned from slave */
for(i=0; i<nSlave; i++)/* for each node(slave) */
{
curRow = i * LINES_ASSIGNED_PER_TIME;/* no. of the first line sent */
Count += assignRows(stid[i], curRow);/* include line num determination */
printf("Now unreturned Rows = %d \n", Count);
}
/* init display enviroment, while slaves are calculating */
//printf("Initing display.................");
/*Window win; /* initialization for a window
Display *display;
GC gc;
resultmap cmap;
unsigned int screen; /* which screen */
initDisplay();
//printf("Init display finished.\n");
/* init variable */
int startRow, nRows, slaveTid;
//int Size = X_RESN * LINES_ASSIGNED_PER_TIME;
int *result = new int [X_RESN * LINES_ASSIGNED_PER_TIME] ;
int Size;
/* receive results */
do
{
//slaveTid = recvResults(PROC_ANY, TAG_ANY, &startRow, &nRows, result);
pvm_upkint(&slaveTid,1,1); /* first data is the slave's id */
pvm_upkint(&startRow,1,1); /* start row no. */
pvm_upkint(&nRows,1,1); /* how many rows */
Size = nRows * X_RESN;
pvm_upkint(result,Size,1);/* result array */
Count -= nRows;
//printf(">>Recved row:%d - %d from slave:%x. Now unreturned Rows = %d\n", startRow, startRow+nRows, slaveTid, Count);
/* send some rows back to the slave came */
curRow += LINES_ASSIGNED_PER_TIME; /* the 1st line of the block to send */
Count += assignRows(slaveTid, curRow);
/* display pixels received */
drawPixels(result, startRow, nRows);
}while(Count>0);
/* record time */
endTime = time(NULL);
usedTime = endTime - startTime;
printf("End at %ld.\n", endTime);
printf("Totally cost: %d\n", usedTime);
XFlush (display);
sleep (200);
for(int i=0; i<nSlave; i++)
{
if (stid[i] > 0)
pvm_kill(stid[i]);/* kill the slaves that were successfully spawned */
}
//killSlaves(nSlave);
// pvm_exit();
// exit(0);
}
/*******************************
* int spawnSlave()
* config pvm, and spawn slaves
* return the num of slaves ( 0 for fail)
********************************/
/*int spawnSlave()
{
int nhost, narch, i, nSlave;
struct pvmhostinfo *hostp[MAX_SLAVES];
//get the state of the pvm, also get num of machines
if (pvm_config(&nhost,&narch,hostp) < 0)
{
printf("PVM config error!\n");
return 0;
}
printf("There are %d machines!\n", nhost);
if(nhost<=0)
{
return 0;
}
/* fork slaves, total num = nhost
nSlave = nhost;
stid = new int[nSlave];/* array to put slaves' id(s)
if (pvm_spawn(SLAVENAME, (char**)0, 0, "", nSlave, stid) < 0)
{
printf("Failed to spawn slaves!\n");
killSlaves(nSlave);
return 0;
}
printf("Spawned %d slaves. They are: ", nSlave);
for(i=0; i<nSlave; i++)
{
printf(" %x\t", stid[i]);
}
printf("\n");
return nSlave;
}
/***************************
* kill the slaves
* param nSlave : num of the slaves to kill
void killSlaves(int nSlave)
{
for(int i=0; i<nSlave; i++)
{
if (stid[i] > 0)
pvm_kill(stid[i]);/* kill the slaves that were successfully spawned
}
}
*/
/*****************************
* int assignRows(..)
* send rows of data (only startRow and nRows)
* or TERMINATOR_TAG if no lines left
* return num of the rows sent this time
******************************/
int assignRows(int slaveTid,int startRow)
{
int nRows;
///* init to send */
pvm_initsend(ENCODING);
///* calculate num of rows to send */
if(startRow >= Y_RESN) /* all lines have been assigned */
{
//printf("No more lines to assign, slave: %x can quit.\n", slaveTid);
pvm_send(slaveTid, TERMINATOR_TAG);/* send term msg */
nRows = 0;
}
else
{
if((startRow+LINES_ASSIGNED_PER_TIME) >= Y_RESN) /* less than a block(100 rows) left */
{
nRows = Y_RESN - startRow;
//printf("Only %d lines left, assigned row:%d - %d to slave: %x\n", nRows, startRow, Y_RESN, slaveTid);
}
else
{
nRows = LINES_ASSIGNED_PER_TIME;
//printf("Assign row:%d - %d to slave: %x\n", startRow, startRow+nRows, slaveTid);
}
/* pk and send */
pvm_pkint(&startRow,1,1); /* start row no. */
pvm_pkint(&nRows,1,1); /* how many rows */
if(pvm_send(slaveTid, DATA_TAG) <0 )
{
printf("Send data failed!\n");
}
}
return nRows; /* num of the rows sent this time */
}
/*******************************
* int recvResults(...)
* receive rows of data(result of each pixel)
* return the slave's id (upk from the packet data)
*******************************/
/*int recvResults(int slaveTid, int tag, int *startRow, int *nRows, int result[])
{
int sid, Size;
if(pvm_recv(slaveTid,tag)<0)
{
printf("Recv data failed!\n");
}
/* unpacket
pvm_upkint(&sid,1,1); /* first data is the slave's id
pvm_upkint(startRow,1,1); /* start row no.
pvm_upkint(nRows,1,1); /* how many rows
Size = (*nRows) * X_RESN;
pvm_upkint(result,Size,1);/* result array
return sid; /* return num of received rows
}
*/
/******************************
* display pixels received recently
* from startRow to (startRow + nRows)
* their results are stored in result[]
*******************************/
void drawPixels(int result[], int startRow, int nRows)
{
int x,y;
int i=0;
int tempC;
XColor xcolor;
for(y=startRow; y<(startRow+nRows); y++) /* y means row */
{
for(x=0; x<X_RESN; x++) /* x means col */
{
i++;
tempC = result[i] * result[i] * 5;
if(result[i]==MAX_ITER) /* foregroud : dark */
{
xcolor.red = 65535U - (unsigned int) tempC ;
xcolor.green = 65535U - (unsigned int) tempC ;
xcolor.blue = 65535U - (unsigned int) tempC ;
if (XAllocColor (display,cmap, &xcolor))
{
XSetForeground (display, gc, xcolor.pixel);
}
XDrawPoint (display, win, gc, y, x); /* (row,col) */
}
else if(result[i] >= MAX_ITER/4 ) /* red, cut down g&b */
{
xcolor.red = 65535U - (unsigned int) tempC ;
xcolor.green = 0;
xcolor.blue = 65535U - (unsigned int) tempC ;
if (XAllocColor (display,cmap, &xcolor))
{
XSetForeground (display, gc, xcolor.pixel);
}
XDrawPoint (display, win, gc, y, x);
}
else if(result[i] >= MAX_ITER/8) /* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
{
xcolor.red = 0;
xcolor.green = 65535U - (unsigned int) tempC ;
xcolor.blue = 0;
if (XAllocColor (display,cmap, &xcolor))
{
XSetForeground (display, gc, xcolor.pixel);
}
XDrawPoint (display, win, gc, y, x);
}
else if(result[i] >= MAX_ITER/10) /* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
{
xcolor.red = 65535U - (unsigned int) tempC;
xcolor.green = 65535U - (unsigned int) tempC ;
xcolor.blue = 0 ;
if (XAllocColor (display,cmap, &xcolor))
{
XSetForeground (display, gc, xcolor.pixel);
}
XDrawPoint (display, win, gc, y, x);
}
else if(result[i] >= MAX_ITER/16) /* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
{
xcolor.red = 0;
xcolor.green = 0;
xcolor.blue = 65535U - (unsigned int) tempC ;
if (XAllocColor (display,cmap, &xcolor))
{
XSetForeground (display, gc, xcolor.pixel);
}
XDrawPoint (display, win, gc, y, x);
}
else if(result[i] >= MAX_ITER/20) /* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
{
xcolor.red = 0;
xcolor.green = 65535U - (unsigned int) tempC ;
xcolor.blue = 65535U - (unsigned int) tempC ;
if (XAllocColor (display,cmap, &xcolor))
{
XSetForeground (display, gc, xcolor.pixel);
}
XDrawPoint (display, win, gc, y, x);
}
else if( result[i] >= MAX_ITER/50 ) /* yellow, depend on r&g, cut down b */
{
xcolor.red = 65535U - (unsigned int)tempC*500;
xcolor.green = 65535U - (unsigned int)tempC*500;
xcolor.blue = 65535U - (unsigned int)tempC*500;
if (XAllocColor (display,cmap, &xcolor))
{
XSetForeground (display, gc, xcolor.pixel);
}
XDrawPoint (display, win, gc, y, x);
}
}
}/* for (each pixel) */
}
/******************************
* config to display
******************************/
void initDisplay()
{
unsigned int width, height, /* window size */
x, y, /* window position */
border_width, /*border width in pixels */
display_width, display_height; /* size of screen */
char *window_name = "Mandelbrot Set",
*display_name = NULL;
unsigned long valuemask = 0;
XGCValues values;
XSizeHints size_hints;
Pixmap bitmap;
XPoint points[800];
FILE *fp, *fopen ();
char str[100];
XSetWindowAttributes attr[1];
/* connect to Xserver */
if ( (display = XOpenDisplay (display_name)) == NULL ) {
fprintf (stderr, "drawon: cannot connect to X server %s\n",
XDisplayName (display_name) );
exit (-1);
}
/* get screen size */
screen = DefaultScreen (display);
display_width = DisplayWidth (display, screen);
display_height = DisplayHeight (display, screen);
/* set window size */
width = X_RESN;
height = Y_RESN;
/* set window position */
x = 0;
y = 0;
/* create opaque window */
border_width = 4;
win = XCreateSimpleWindow (display, RootWindow (display, screen),
x, y, width, height, border_width,
BlackPixel (display, screen), WhitePixel (display, screen));
cmap = DefaultColormap (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 = 300;
size_hints.min_height = 300;
XSetNormalHints (display, win, &size_hints);
XStoreName(display, win, window_name);
/* create graphics context */
gc = XCreateGC (display, win, valuemask, &values);
XSetBackground (display, gc, WhitePixel (display, screen));
XSetForeground (display, gc, BlackPixel (display, screen));
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -