Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis12/src/compiler/c-target/fragments/par-run-nobar.in
ViewVC logotype

View of /branches/vis12/src/compiler/c-target/fragments/par-run-nobar.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2077 - (download) (annotate)
Mon Nov 5 11:51:35 2012 UTC (7 years, 10 months ago) by jhr
File size: 3596 byte(s)
  Optimize case where no barrier synchronization is required in parallel implementation.
/* Worker thread for when we do not need super-step synchronization */
static void *@PREFIX@Worker (void *arg)
{
    WorkerArg_t *myArg = (WorkerArg_t *)arg;
    @PREFIX@World_t *wrld = myArg->wrld;
    @PREFIX@Globals_t *glob = wrld->globals;
    Diderot_Sched_t *sched = wrld->sched;
    Strand_t *strand = &(wrld->strandDesc[0]);

  // iterate until there is no more work to do
    int blkStart, blkSize;
    int numDead = 0;
    int numStabilized = 0;
    do {
      // grab a block of strands
	pthread_mutex_lock (&sched->lock);
	    blkStart = sched->nextStrand;
	    blkSize = (sched->numAvail >= BLOCK_SIZE) ? BLOCK_SIZE : sched->numAvail;
	    sched->numAvail -= blkSize;
	    sched->nextStrand += blkSize;
	pthread_mutex_unlock (&sched->lock);
      // update the strands
	for (int i = blkStart;  i < blkStart+blkSize;  i++) {
	  // run the strand to completion, or until the step limit is exceeded
	    @STRANDTY@ *inState = wrld->inState[i];
	    @STRANDTY@ *outState = wrld->outState[i];
	    StrandStatus_t sts = wrld->status[i];
	    uint32_t limit = myArg->maxNSteps;
	    while ((! sts) && (limit-- > 0)) {
	      // swap in and out
		@STRANDTY@ *tmp = inState;
		inState = outState;
		outState = tmp;
		sts = @STRAND@_Update(glob, inState, outState);
	    }
	  // finalize the strand state as necessary
	    switch (sts) {
	      case DIDEROT_STABILIZE:
              // stabilize the strand's state.  Note that the outState has been set by
              // the last call to update, so we make the inState be the target of the
              // stabilize method.
		@STRAND@_Stabilize(glob, outState, inState);
		memcpy (outState, inState, strand->stateSzb);
		wrld->status[i] = DIDEROT_STABLE;
		numStabilized++;
		break;
	      case DIDEROT_DIE:
		wrld->status[i] = DIDEROT_DIE;
		numDead++;
		break;
	      default:
		assert (sts == wrld->status[i]);
		break;
	    }
	}
    } while (blkSize > 0);

  // update scheduler state
    pthread_mutex_lock (&sched->lock);
	sched->numActive -= numDead;
	sched->numActive -= numStabilized;
	sched->numIdle++;
    pthread_mutex_unlock (&sched->lock);

    pthread_cond_signal (&sched->runWait);

    return 0;

}

//! Run the Diderot program (parallel version)
//! \param wrld the world-state of the Diderot program
//! \param maxNSteps the limit on the number of super steps; 0 means unlimited
//! \return the number of steps taken.
uint32_t @PREFIX@Run (@PREFIX@World_t *wrld, uint32_t maxNSteps)
{
    Diderot_Sched_t *sched = wrld->sched;

    if (maxNSteps == 0) maxNSteps = 0xffffffff;  // essentially unlimited

  // Start worker threads
    int nWorkers = sched->numWorkers;
    WorkerArg_t *args = NEWVEC(WorkerArg_t, nWorkers);
    if (wrld->verboseFlg) fprintf (stderr, "initializing %d workers ...\n", nWorkers);
    double t0 = airTime();
    sched->numWorkers = nWorkers;
    sched->numAvail = wrld->numStrands;
    sched->numIdle = 0;
    sched->numSteps = 0;
    sched->nextStrand = 0;
    for (int i = 0; i < nWorkers; i++) {
        pthread_t pid;
        args[i].wrld = wrld;
        args[i].maxNSteps = maxNSteps;
        args[i].id = i;
        if (pthread_create (&pid, NULL, @PREFIX@Worker, (void *)&(args[i])) != 0) {
            fprintf (stderr, "unable to create worker thread\n");
            exit (1);
        }
        pthread_detach (pid);
    }

  // wait for the computation to finish
    pthread_mutex_lock (&sched->lock);
	while (sched->numIdle < nWorkers)
	    pthread_cond_wait (&sched->runWait, &sched->lock);
    pthread_mutex_unlock (&sched->lock);

    FREE(args);

    return sched->numSteps;
}


root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0