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

SCM Repository

[diderot] View of /trunk/src/lib/parallel-target/cpu.c
ViewVC logotype

View of /trunk/src/lib/parallel-target/cpu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1232 - (download) (as text) (annotate)
Mon May 16 23:37:52 2011 UTC (10 years ago) by jhr
File size: 3027 byte(s)
  Porting many changes from the pure-cfg branch, including value numbering
  and support for parallel execution on SMP systems.
/*! \file cpu.c
 *
 * \author John Reppy
 */

/*
 * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 */

#include "Diderot/diderot.h"
#if defined (__APPLE__)
#  include <sys/sysctl.h>
#endif
#ifdef HAVE_LIBNUMA
#  include <numa.h>
#endif
#include <errno.h>

/*! \brief determine the number of CPUs */
bool GetNumCPUs (CPUInfo_t *info)
{
#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
   */
    FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
    char buf[1024];
    if (cpuinfo != NULL) {
	int maxProcId = 0, maxNodeId = 0, maxCoreId = 0, nCores = 0;
	while (fgets(buf, sizeof(buf), cpuinfo) != 0) {
	    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;
	    }
	}
	fclose (cpuinfo);

#ifdef HAVE_LIBNUMA
	info->numHWThreads = info->numHWCores = maxProcId + 1;
	info->numHWNodes  = numa_max_node()+1;
	info->numThdsPerCore = 1;
	info->numCoresPerNode = info->numHWThreads / info->numHWNodes;
#else
	info->numHWNodes = maxNodeId + 1;
	info->numHWCores = info->numHWNodes * nCores;
	info->numHWThreads = maxProcId + 1;
	info->numCoresPerNode = nCores;
	info->numThdsPerCore = info->numHWThreads / info->numHWCores;
#endif

	return true;
    }
    else {
	fprintf(stderr, "unable to determine the number of processors\n");
	return false;
    }
#elif defined(__APPLE__)
    size_t	len = sizeof(int);

  /* the number of nodes */
    if (sysctlbyname("hw.packages", &(info->numHWNodes), &len, 0, 0) < 0) {
	if (errno == ENOENT) {
	  // "hw.packages" is not known
	    info->numHWNodes = 1;
	}
	else {
	    fprintf(stderr, "unable to determine the number of nodes\n");
	    return false;
	}
    }

  /* the number of cores */
    if (sysctlbyname("hw.physicalcpu", &(info->numHWCores), &len, 0, 0) < 0) {
	fprintf(stderr, "unable to determine the number of physical CPUs\n");
	return false;
    }

  /* the number of hardware threads */
    if (sysctlbyname("hw.logicalcpu", &(info->numHWThreads), &len, 0, 0) < 0) {
	if (errno == ENOENT) {
	  // "hw.packages" is not known
	    info->numHWThreads = info->numHWCores;
	}
	else {
	    fprintf(stderr, "unable to determine the number of logical CPUs\n");
	    return false;
	}
    }

    info->numCoresPerNode = info->numHWCores / info->numHWNodes;
    info->numThdsPerCore = info->numHWThreads / info->numHWCores;

    return true;
#else
    return false;
#endif

} /* end of GetNumCPUs */

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