[comp.sys.sgi] Parallel Programming - m_sync Problem

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.