⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t_initialize.c

📁 CCSM Research Tools: Community Atmosphere Model (CAM)
💻 C
字号:
#include <stdlib.h>  /* malloc */#include <unistd.h>  /* sysconf */#include "gpt.h"/* ** Array (1 per thread) of linked lists of timers, and last timer in each list*/struct node **timers = NULL;struct node **last = NULL;long ticks_per_sec;/*** Define lock arrays depending upon the type of threading done*/#if ( defined THREADED_OMP )omp_lock_t lock;#elif ( defined THREADED_PTHREADS )pthread_mutex_t t_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_t *threadid;#endiffloat *overhead;                   /* wallclock estimate of timer overhead */int *max_indent_level;             /* maximum indentation level */int numthreads            = 1;     /* number of threads.  1 is for no threading */Boolean t_initialized     = false; /* whether t_initialize has been called */Boolean wallenabled       = false; /* wallclock timer stats enabled */Boolean usrsysenabled     = false; /* usr & sys timer stats enabled */Boolean pclenabled        = false; /* enable PCL library */     Boolean pcl_cyclesenabled = false; /* enable PCL cycle count */int pcl_cyclesindex       = -1;    /* index for PCL cycle count */struct PossibleEvent possible_event[] = {  {usrsys,               true,  "Usr Sys   "},  {wall,                 true,  "Wallclock "},#ifdef HAVE_PCL  {pcl_start,            false, "          "},  /* bracket PCL entries */  {pcl_l1dcache_miss,    false, "l1 D miss "},  {pcl_l2cache_miss,     false, "L2 miss   "},  {pcl_cycles,           false, "Cycles    "},  {pcl_elapsed_cycles,   false, "E-Cycles  "},  {pcl_fp_instr,         false, "FP instr  "},  {pcl_loadstore_instr,  false, "L/S instr "},  {pcl_instr,            false, "Instruct  "},  {pcl_stall,            false, "Stall     "},  {pcl_end,              false, "          "},  /* bracket PCL entries */#endif};struct Event **event = NULL;int nevent = 0;int npossible = sizeof (possible_event) / sizeof (struct PossibleEvent);/*** Needed by PCL library: otherwise unused*/PCL_DESCR_TYPE *descr;int counter_list[PCL_COUNTER_MAX];int ncounter = 0;                  /* number of PCL counters */PCL_CNT_TYPE *overhead_pcl;        /* overhead counter (cycles) *//*** t_initialize (): Initialization routine must be called from single-threaded**   region before any other timing routines may be called.  The need for this**   routine could be eliminated if not targetting timing library for threaded**   capability. **** return value: 0 (success) or -1 (failure)*/int t_initialize (){  int n;             /* index */  int nbytes;        /* number of bytes for malloc */  int ret;           /* return code *//*** Determine number of ticks per second for conversion use by other t_pr(), t_stamp()*/  if ((ticks_per_sec = sysconf (_SC_CLK_TCK)) == -1)    return t_error ("t_initialize: token _SC_CLK_TCK is not defined\n");#if ( ! defined DISABLE_TIMERS )  if (t_initialized)    return t_error ("t_initialize has already been called\n");#if ( defined THREADED_OMP )  /*  ** OMP: must call init_lock before using the lock (get_thread_num())  */  omp_init_lock (&lock);  numthreads = omp_get_max_threads();#elif ( defined THREADED_PTHREADS )  numthreads = MAX_THREADS;#endif  /*  ** Allocate space for global arrays  */  nbytes = numthreads * sizeof (struct node *);  if ((timers = (struct node **) malloc (nbytes)) == 0)    return t_error ("malloc failure: %d items\n", numthreads);  if ((last = (struct node **) malloc (nbytes)) == 0)    return t_error ("malloc failure: %d items\n", numthreads);  nbytes = numthreads * sizeof (float);  if ((overhead = (float *) malloc (nbytes)) == 0)    return t_error ("malloc failure: %d items\n", numthreads);  nbytes = numthreads * sizeof (PCL_CNT_TYPE);  if ((overhead_pcl = (PCL_CNT_TYPE *) malloc (nbytes)) == 0)    return t_error ("malloc failure: %d items\n", numthreads);  nbytes = numthreads * sizeof (int);  if ((max_indent_level = (int *) malloc (nbytes)) == 0)    return t_error ("malloc failure for %d items\n", numthreads);  /*  ** Initialize array values  */  for (n = 0; n < numthreads; n++) {    timers[n] = 0;    last[n] = 0;    overhead[n] = 0.;    overhead_pcl[n] = 0;    max_indent_level[n] = 0;  }#ifdef THREADED_PTHREADS  /*  ** In the pthreads case, we must manage the threadid array which maps  ** physical thread id's to logical id's  */  nbytes = numthreads * sizeof (pthread_t);  if ((threadid = (pthread_t *) malloc (nbytes)) == 0)    return t_error ("malloc failure for %d items\n", numthreads);  /*  ** Reset numthreads to 1 and define the threadid array now that initialization   ** is done.  */  threadid[0] = pthread_self ();  numthreads = 1;#endif  if (get_thread_num () > 0)     return t_error ("t_initialize: should only be called by master thread\n");  for (n = 0; n < npossible; n++) {    if (possible_event[n].enabled) {      if (possible_event[n].name == usrsys)	usrsysenabled = true;      if (possible_event[n].name == wall)	wallenabled = true;      if ((event = realloc (event, (nevent+1) * sizeof (struct Event *))) == NULL)	return t_error ("realloc failure\n");      if ((event[nevent] = malloc (sizeof (struct Event))) == NULL)	return t_error ("realloc failure\n");      event[nevent]->name = possible_event[n].name;      strcpy (event[nevent]->string, possible_event[n].string);#ifdef HAVE_PCL      /*      ** Set up PCL stuff based on what t_setoption has provided.      */      if (event[nevent]->name > pcl_start && event[nevent]->name < pcl_end) {	pclenabled = true;	event[nevent]->index = ncounter;	switch (possible_event[n].name) {	case pcl_l1dcache_miss:	  counter_list[ncounter++] = PCL_L1DCACHE_MISS;	  break;	  	case pcl_l2cache_miss: 	  counter_list[ncounter++] = PCL_L2CACHE_MISS;	  break;	  	case pcl_cycles: 	  pcl_cyclesindex = ncounter;	  pcl_cyclesenabled = true;	  counter_list[ncounter++] = PCL_CYCLES;	  break;	case pcl_elapsed_cycles: 	  counter_list[ncounter++] = PCL_ELAPSED_CYCLES;	  break;	case pcl_fp_instr: 	  counter_list[ncounter++] = PCL_FP_INSTR;	  break;	case pcl_loadstore_instr: 	  counter_list[ncounter++] = PCL_LOADSTORE_INSTR;	  break;	case pcl_instr: 	  counter_list[ncounter++] = PCL_INSTR;	  break;	case pcl_stall: 	  counter_list[ncounter++] = PCL_STALL;	  break;		default:	  break;	}      }#endif      ++nevent;    }  }#ifdef HAVE_PCL  if (ncounter > 0) {    int thread;         /* thread number */    nbytes = numthreads * sizeof (PCL_DESCR_TYPE);    if ((descr = (PCL_DESCR_TYPE *) malloc (nbytes)) == 0)      return t_error ("malloc failure: %d items\n", numthreads);    /*    ** PCLinit must be called on a per-thread basis.  Therefore must make the call here    ** rather than in t_initialize.  null timer list flags not initialized.    ** Also, the critical section is necessary because PCLstart appears not to be    ** thread-safe.    */#pragma omp parallel for        for (thread = 0; thread < numthreads; thread++) {      unsigned int flags;           /* mode flags needed by PCL */#pragma omp critical      {	if ((ret = PCLinit (&descr[thread])) != PCL_SUCCESS)	  return t_error ("unable to allocate PCL handle for thread %d. %s\n",			  thread, t_pclstr (ret));	/*	** Always count user mode only	*/      	flags = PCL_MODE_USER;	if ((ret = PCLquery (descr[thread], counter_list, ncounter, flags)) != PCL_SUCCESS)	  return t_error ("Bad return from PCLquery thread %d: %s\n", thread, t_pclstr (ret));	if ((ret = PCLstart (descr[thread], counter_list, ncounter, flags)) != PCL_SUCCESS)	  return t_error ("PCLstart failed thread=%d: %s\n", thread, t_pclstr (ret));      }    }  }#endif  t_initialized = true;#endif  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -