cindy@cesdis2.gsfc.nasa.gov (Cindy Starr) (04/17/91)
Hi folks! I've been playing with the parallel programming library on our SGI 4D/240VGX. Has anyone gotten m_sync to work? The man page says: "When m_sync is called by each thread, it waits at that point for all other threads to call m_sync." This doesn't appear to be happening in my test program below. Does anyone know why? Also, are there any problems in using the Sequent routines (m_...) together with the lock & semaphore routines (us..) and area routines (a..)? Has anyone seen any documentation on the task routines other than the man pages? They don't seem to be in my version of the parallel programming manual. If anyone has SHORT examples of using the parallel programming library, they'd be a great help! Cindy cindy@cesdis2.gsfc.nasa.gov ----------------------- cut here ---------------------- /* * * Test 1 * * A test of the parallel programming primitives * on the Iris 4D/240VGX workstation. * * Testing the Sequent multitasking (m_...) routines. * * This is an example of a homogeneous parallel * program with static work allocation. * */ #include "stdio.h" #include "sys/types.h" #include "sys/times.h" #include "ulocks.h" #include "sys/param.h" /* defaults if no command line option given a */ #define MAXLOOP 16000 #define MAXTHREADS 10 int nprocs; long float total = 0.0; long float part[MAXTHREADS]; int nloops = 100; int eachpiece; /* * The MAIN Program * */ main (argc, argv) int argc; char **argv; { extern void piece(); extern void parse_args(); struct tms tim; long float stime, eltime; parse_args(argc,argv); /* Get any command line args */ if (nloops > MAXLOOP) nloops = MAXLOOP; eachpiece = (nloops/nprocs); /* Determine the size of each chunk */ m_set_procs(nprocs); /* Set the desired # of processes */ stime = times(&tim); m_fork(piece); /* Fork n processes running "piece" */ eltime = times(&tim)-stime; m_kill_procs(); /* Kill all the extra processes */ printf("\n Final Total: %5.2lf \n", total); printf("\nElapsed time (real): %5.2lf \n", (eltime/HZ)); } /* * piece process * nprocs instances of this routine are * forked from main when m_fork is called. * */ void piece() { int starti, endi, myid; int i, pause; myid = m_get_myid(); /* Get the current Process ID */ printf("My process id is %i\n",myid); starti = myid * eachpiece; endi = starti + eachpiece; pause = starti + ( 4 * myid ); part[myid] = 0; for (i = starti; i < endi; i++) { part[myid] += i; /* Accumulate partial sum */ if (i == pause) { m_sync; printf("Sync called for PID %i at %i\n",myid,i); } switch (myid) { case 0: printf("PID %i: i = %i\n",myid,i); break; case 1: printf(" PID %i: i = %i\n",myid,i); break; case 2: printf(" PID %i: i = %i\n",myid,i); break; case 3: printf(" PID %i: i = %i\n",myid,i); break; default: break; } } printf("\nPartial Total %i: %5.2lf \n", myid, part[myid]); m_lock(); /* Add partial sum to total sum */ total += part[myid]; m_unlock(); } /* * parse_args * This routine reads in the command line arguments * and stores the values in the related variables. * */ void parse_args(argc,argv) int argc; char **argv; { extern char *optarg; int c; nprocs = m_get_numprocs(); /* Set the default # of processes */ while ((c = getopt(argc,argv, "r:p:")) != EOF) switch (c) { case 'r': nloops = atoi(optarg); break; case 'p': nprocs = atoi(optarg); m_set_procs(nprocs); break; case '?': default: fprintf(stderr, "Usage: pi [-r nloops] [-n nprocs] \n"); exit(-1); } printf("Processes:%d nloops: %d\n", nprocs, nloops); }
micah@flobb4.csd.sgi.com (Micah Altman) (04/18/91)
In <4924@dftsrv.gsfc.nasa.gov> cindy@cesdis2.gsfc.nasa.gov (Cindy Starr) writes: > "When m_sync is called by each thread, it waits > at that point for all other threads to call > m_sync." > > This doesn't appear to be happening in my test > program below. Does anyone know why? Actually, I believe m_sync is working just fine. I think the reason things _appear_ to be screwy is that when you do a printf() across multiple threads you'll see the results in a very arbitrary order ( depending on timing of the printf , internal sempahores and file flushing ). In your test program instead of doing something like this: printf("Syncing.... m_sync(); Do this: m_sync(); printf(" Synced and released "); fflush(); m_sync(); And you'll see that all the threads are released at the same time... ( You do the second sync to make sure every thread has printed out and flushed the message, before every thread can continue. ) > > Also, are there any problems in using the Sequent > routines (m_...) together with the lock & semaphore > routines (us..) and area routines (a..)? Has anyone No problem mixing m_* and us* routines. I don't know about the amalloc calls, use the usmalloc calls instead. > seen any documentation on the task routines other > than the man pages? They don't seem to be in my > version of the parallel programming manual. > You may want to avoid the task* stuff, I thinks its going away in the next release- though I'm not positive on this. > If anyone has SHORT examples of using the parallel > programming library, they'd be a great help! Also, there is a class in Parallel Programming offered by SGI , you can call 1-800-800-4SGI to get details. -- "Entia non sunt multiplicanda sine necessitate." - William of Ockham Micah Altman, "Computational Juggler" micah@csd.sgi.com Phone (415) 335-1866 FAX (415) 965-2309 Disclaimer: Everything in this document is a lie.