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

SCM Repository

[diderot] View of /branches/vis15/src/compiler/target-cpu/fragments/par-run-nobsp.in
ViewVC logotype

View of /branches/vis15/src/compiler/target-cpu/fragments/par-run-nobsp.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4797 - (download) (annotate)
Mon Oct 24 16:59:27 2016 UTC (2 years, 9 months ago) by jhr
File size: 4099 byte(s)
working on parallel target
struct CACHE_ALIGN worker_arg {
    world	*_wrld;		//!< world pointer
    uint32_t	_maxNSteps;	//!< maximum number of steps to take; 0 == infinity
    uint32_t	_nSteps;	//!< max number of steps taken by a strand in call to run
    uint32_t	_nStable;	//!< number of strands that stabilized in call to run
    uint32_t	_nDead;		//!< number of strands that died in call to run
};

/* Worker task for when we do not need super-step synchronization */
static void worker (void *arg)
{
    worker_arg *myArg = reinterpret_cast<worker_arg *>(arg);
    world *wrld = myArg->_wrld;
#ifndef DIDEROT_NO_GLOBALS
    globals *glob = wrld->_globals;
#endif
    diderot::scheduler *sched = wrld->_sched;

  // iterate until there is no more work to do
    int blkStart, blkSize;
    uint32_t numDead = 0;
    uint32_t numStabilized = 0;
    uint32_t maxSteps = 0;
    uint32_t maxNSteps = myArg->_maxNSteps;
    strand_array::sched_block *blk;
    while ((blk = wrld->_strands.get_block()) != nullptr) {
	uint32_t nActive = blk->_nActive;
	uint32_t nStable = blk->_nStable;
      // update the strands
        for (auto ix = wrld->_strands.begin_active(blk);
	    ix != wrld->_strands.end_active(blk);
	) {
          // run the strand to completion, or until the step limit is exceeded
	    diderot::strand_status sts = wrld->_strands.status(ix);
	    uint32_t nSteps = 0;
	    while ((! sts) && (nSteps < maxNSteps)) {
		nSteps++;
		sts = wrld->_strands.strand_update(@UPDATE_ARGS_IN_WRLD@ix);
	    }
	    switch (sts) {
	      case diderot::kStabilize:
	      // stabilize the strand's state.
		ix = wrld->_strands.strand_stabilize (blk, @STABILIZE_ARGS_IN_WRLD@ix);
		break;
#ifdef DIDEROT_HAS_STRAND_DIE
	      case diderot::kDie:
		ix = wrld->_strands.kill (blk, ix);
		numDead++;
		break;
#endif
	      default:
		assert (sts == wrld->_strands.status(ix));
		ix = wrld->_strands.next_active(blk, ix);
		break;
	    }
	    if (maxSteps < nSteps) maxSteps = nSteps;
        }
	numStabilized += (blk->_nStable - nStable);
    }

  // update global counts of active and stable strands
    myArg->_nSteps = maxSteps;
    myArg->_nStable = numStabilized;
    myArg->_nDead = numDead;

}

//! Run the Diderot program (parallel version)
//! \param maxNSteps the limit on the number of super steps; 0 means unlimited
//! \return the number of steps taken, or 0 on error.
uint32_t world::run (uint32_t maxNSteps)
{
    if (this->_stage < diderot::POST_CREATE) {
	this->error ("attempt to run uninitialized program\n");
        return 0;
    }
    else if (this->_stage == diderot::DONE) {
        return 0;
    }
    else if (this->_stage == diderot::POST_CREATE) {
#ifdef DIDEROT_HAS_GLOBAL_START
        this->global_start();
#endif
        this->_stage = diderot::RUNNING;
    }
    assert (this->_stage == diderot::RUNNING);

    diderot::scheduler *sched = this->_sched;

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

  // initialize per-worker info
    worker_arg *args = new worker_arg[sched->_numWorkers];
    for (int i = 0;  i < sched->_numWorkers;  i++) {
	worker_arg *p = &args[i];
	p->_wrld = this;
	p->_maxNSteps = maxNSteps;
	p->_nSteps = 0;
	p->_nStable = 0;
	p->_nDead = 0;
	sched->_info[i]._data = p;
    }

    double t0 = airTime();

  // Start worker threads
    if (this->_verbose) {
        std::cerr << "run with " << this->_strands.num_alive() << " strands / "
	    << sched->_numWorkers << " workers ..." << std::endl;
    }
    sched->_gate.release_workers ();

  // wait for the computation to finish
    sched->_gate.controller_wait ();

  // update global counts of active and stable strands
    uint32_t nSteps = 0;
    for (uint32_t i = 0;  i < sched->_numWorkers;  i++) {
	nSteps = std::max (nSteps, args[i]._nSteps);
	this->_strands._nActive -= args[i]._nStable + args[i]._nDead;
	this->_strands._nStable += args[i]._nStable;
    }
    delete[] args;

    t0 = airTime() - t0;
    if (this->_verbose) {
        std::cerr << "done in " << t0 << " seconds" << std::endl;
    }
    this->_run_time += t0;

    return nSteps;

} // world::run

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