/* CRCW Quickhull algorithm, DC strategy * * computes convex hull of N points using p processors * * in expected time O((N/p)log N). C.W. Kessler 10/96 */ /* FOR TIME MEASUREMENT, DELETE THE CALLS TO line() --- * THEY ACCOUNT FOR MORE THAN 95 % OF THE RUN TIME! */ #include #include #include #include #include #include sh int N; /* the number of points */ sh double *x, *y; /* x and y point coordinates */ sh int *belongs_to_hull; /* the result vector; indicates whether a point belongs to the hull*/ sh simple_lock screen = 0; #define PIXELS 512 /*extents of generated X-Pixmap picture*/ sh double factor = 0.00000024; /*fuer 512*/ /* output routines: */ async void set_point( int x, int y, int width, int color ) { pr int i, j; for (i=1-width; i0.0) #define est_work(n) \ /*float value estimating work to be done for size-n problem*/\ ((float)((n) * (ilog2(n)+1))) sync int *delete_right( sh int *pt, sh int *num, sh int p1, sh int p2 ) { pr int j; sh int leftcnt; sh int *left; sh int n = *num; sh int p = 0; $ = mpadd( &p, 1 ); /* renumber and determine number of processors */ farm pprintf("delete_right P%d,P%d, n=%d\n", p1, p2, n ); /* delete all points in pt located right from line p1p2: */ farm if ($==0) left = (int *) shmalloc( n ); left[0]=p1; left[1]=p2; leftcnt = 2; for (j=$; j x[p2]) p2 = i; } belongs_to_hull[p1] = 1; belongs_to_hull[p2] = 1; *minx = p1; *maxx = p2; } sync int seq_pivotize( sh int *pt, sh int n ) /* n>=3 is assumed */ /* as pivot, select the point in pt[]-{p1,p2} with maximal * cross_prod( pivot-p1, p2-p1 ) */ { sh int i, p1=pt[0], p2=pt[1]; sh int pivotpos = 2; sh double maxcross = cross(pt[2], p1, p2); for (i=3; i maxcross) { maxcross = newcross; pivotpos = i; } } return pt[pivotpos]; } sync int par_pivotize( sh int *pt, sh int n ) /* n>=p+3 is assumed */ { sh int p=0; sh int p1=pt[0], p2=pt[1]; pr int mypivotpos; pr double mymaxcross; sh double *cval; sh int *cidx; sh int s; pr int i; $ = mpadd( &p, 1 ); /* renumber processors within the group */ mypivotpos = $+2; mymaxcross = cross(pt[$+2], p1, p2); for (i=p+2+$; i mymaxcross) { mymaxcross = mynewcross; mypivotpos = i; } } cval = (double *) shalloc(p*sizeof(double)); /* temp. array for this fn.*/ cidx = (int *) shalloc(p*sizeof(int)); /* temp. array for this fn. */ cval[$] = mymaxcross; cidx[$] = mypivotpos; for (s=1; sp+2) pivot = par_pivotize( pt, n ); else pivot = seq_pivotize( pt, n ); belongs_to_hull[pivot] = 1; line (x[p1],y[p1],x[pivot],y[pivot],0x00ff00,2); /* draw edge (p1,pivot) */ line (x[pivot],y[pivot],x[p2],y[p2],0x00ff00,2); /* draw edge (pivot,p2) */ /* determine subproblems: */ n1 = n2 = n; S1 = delete_right( pt, &n1, p1, pivot ); S2 = delete_right( pt, &n2, pivot, p2 ); /* determine amount of processors dedicated to each sub-problem:*/ firstrightproc = (int) ((float)p * est_work(n1) / est_work(n) ); if (firstrightproc == 0 && n1 > 0) firstrightproc = 1; if ($ < firstrightproc) /*split group of processors: */ qh( S1, n1 ); else qh( S2, n2 ); } sh unsigned int starttime, stoptime; void main( void ) { if (__PROC_NR__==0) { printf("Enter N = "); scanf("%d", &N ); printf("\ngenerate %d random points.\n", N); } srand( 1717171 ); /* seed random generator */ start { sh int p = groupsize(); sh int *pt = (int *) shalloc( N * sizeof(int) ); sh int minxpt, maxxpt; sh int *upper = (int *) shalloc( N * sizeof(int) ); sh int *lower = (int *) shalloc( N * sizeof(int) ); sh int uppercnt, lowercnt; pr int j; sh double xj; init_pict( PIXELS+1, PIXELS+1 ); clear_pixels( 1 ); belongs_to_hull = (int *) shalloc( N ); x = (double *) shalloc( N * sizeof(double) ); y = (double *) shalloc( N * sizeof(double) ); seq { /* sequential to get equal problems for varying p */ for (j=0; j=0)?(x):(-(x))) xj = ((double) rand()) * factor; x[j] = ABS(xj); xj = ((double) rand()) * factor; y[j] = ABS(xj); pt[j] = j; set_point( (int) x[j], (int) y[j], 2, 3 ); } starttime = getct(); } for (j=$; j