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

SCM Repository

[diderot] View of /branches/vis15/src/lib/parallel-target/scheduler.cxx
ViewVC logotype

View of /branches/vis15/src/lib/parallel-target/scheduler.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4637 - (download) (as text) (annotate)
Tue Sep 27 02:11:43 2016 UTC (2 years, 11 months ago) by jhr
File size: 4821 byte(s)
  working on merge: add SIMD flags to C++ compiles
/*! \file scheduler.cxx
 *
 * \author John Reppy
 */

/*
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2016 The University of Chicago
 * All rights reserved.
 */

#include "diderot/parallel.hxx"

#if defined (__APPLE__)
#  include <sys/sysctl.h>
#elif defined(HAVE__PROC_CPUINFO)
#  include <cstdio>  // for sscanf
#  include <fstream>
#  ifdef HAVE_LIBNUMA
#    include <numa.h>
#  endif
#endif
#include <errno.h>

namespace diderot {

    bool scheduler::get_cpu_info (world_base *wrld)
    {
#if defined(HAVE__PROC_CPUINFO)
      /* Get information from /proc/cpuinfo.  The interesting
       * fields are:
       *
       *    processor       : <id>          # logical processor id
       *    physical id     : <id>          # node id
       *    core id         : <id>          # core id (per node)
       *    cpu cores       : <n>           # number of cores per node
       */
        std::ifstream cpuinfo("/proc/cpuinfo");
        if (cpuinfo.good()) {
            int maxProcId = 0, maxNodeId = 0, maxCoreId = 0, nCores = 0;
            char buf[1024];
            cpuinfo.getline (buf, sizeof(buf));
            while (cpuinfo.good()) {
                int tmp;
                if (sscanf(buf, "processor : %d", &tmp) == 1) {
                    maxProcId = (tmp > maxProcId) ? tmp : maxProcId;
                }
                else if (sscanf(buf, "physical id : %d", &tmp) == 1) {
                    maxNodeId = (tmp > maxNodeId) ? tmp : maxNodeId;
                }
                else if (sscanf(buf, "core id : %d", &tmp) == 1) {
                    maxCoreId = (tmp > maxCoreId) ? tmp : maxCoreId;
                }
                else if (sscanf(buf, "cpu cores : %d", &tmp) == 1) {
                    nCores = (tmp > nCores) ? tmp : nCores;
                }
                cpuinfo.getline (buf, sizeof(buf));
            }
            cpuinfo.close();
#ifdef HAVE_LIBNUMA
            this->_numHWThreads = this->_numHWCores = maxProcId + 1;
            this->_numHWNodes  = numa_max_node()+1;
            this->_numThdsPerCore = 1;
            this->_numCoresPerNode = this->_numHWThreads / this->_numHWNodes;
#else
            this->_numHWNodes = maxNodeId + 1;
            this->_numHWCores = this->_numHWNodes * nCores;
            this->_numHWThreads = maxProcId + 1;
            this->_numCoresPerNode = nCores;
            this->_numThdsPerCore = this->_numHWThreads / this->_numHWCores;
#endif
            return false;
        }
        else {
            wrld->error ("unable to determine the number of processors\n");
            return true;
        }
#elif defined(__APPLE__)
        size_t      len = sizeof(int);

      /* the number of nodes */
        if (sysctlbyname("hw.packages", &(this->_numHWNodes), &len, 0, 0) < 0) {
            if (errno == ENOENT) {
              // "hw.packages" is not known
                this->_numHWNodes = 1;
            }
            else {
                wrld->error ("unable to determine the number of nodes\n");
                return true;
            }
        }

      /* the number of cores */
        if (sysctlbyname("hw.physicalcpu", &(this->_numHWCores), &len, 0, 0) < 0) {
            wrld->error ("unable to determine the number of physical CPUs\n");
            return true;
        }

      /* the number of hardware threads */
        if (sysctlbyname("hw.logicalcpu", &(this->_numHWThreads), &len, 0, 0) < 0) {
            if (errno == ENOENT) {
              // "hw.packages" is not known
                this->_numHWThreads = this->_numHWCores;
            }
            else {
                wrld->error ("unable to determine the number of logical CPUs\n");
                return true;
            }
        }

        this->_numCoresPerNode = this->_numHWCores / this->_numHWNodes;
        this->_numThdsPerCore = this->_numHWThreads / this->_numHWCores;

        return false;
#else
        return true;
#endif
    }

    scheduler::scheduler ()
        : _numHWNodes(0), _numHWCores(0), _numHWThreads(0), _numCoresPerNode(0),
          _numThdsPerCore(0), _numWorkers(0), _workSize(0), _nextStrand(0),
          _nactive(0), _nstable(0), _navail(0), _nidle(0), _nsteps(0)
    {
        pthread_mutex_init (&this->_lock, nullptr);
        pthread_cond_init (&this->_runWait, nullptr);
    }

    scheduler::~scheduler ()
    {
        pthread_mutex_destroy (&this->_lock);
        pthread_cond_destroy (&this->_runWait);
    }

    void worker_main (void *data)
    {
	worker_info	*myInfo = static_cast<worker_info *>(data);
	scheduler	*sched = myInfo->_sched;

	while (true) {
	    // wait on barrier
	  // check for termination
	    if (sched->_done) {
		return;
	    }
	  // run the task
	    sched->_task (myInfo);
	}

    }

    
} // namepace diderot

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