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

📄 stats.c

📁 体系机构仿真
💻 C
📖 第 1 页 / 共 3 页
字号:
}#endif /* __GNUC__ *//* register a float statistical variable */struct stat_stat_t *stat_reg_float(struct stat_sdb_t *sdb,	/* stat database */	       char *name,		/* stat variable name */	       char *desc,		/* stat variable description */	       float *var,		/* stat variable */	       float init_val,		/* stat variable initial value */	       char *format)		/* optional variable output format */{  struct stat_stat_t *stat;  stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t));  if (!stat)    fatal("out of virtual memory");  stat->name = mystrdup(name);  stat->desc = mystrdup(desc);  stat->format = format ? format : "%12.4f";  stat->sc = sc_float;  stat->variant.for_float.var = var;  stat->variant.for_float.init_val = init_val;  /* link onto SDB chain */  add_stat(sdb, stat);  /* initialize stat */  *var = init_val;  return stat;}/* register a double statistical variable */struct stat_stat_t *stat_reg_double(struct stat_sdb_t *sdb,	/* stat database */		char *name,		/* stat variable name */		char *desc,		/* stat variable description */		double *var,		/* stat variable */		double init_val,	/* stat variable initial value */		char *format)		/* optional variable output format */{  struct stat_stat_t *stat;  stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t));  if (!stat)    fatal("out of virtual memory");  stat->name = mystrdup(name);  stat->desc = mystrdup(desc);  stat->format = format ? format : "%12.4f";  stat->sc = sc_double;  stat->variant.for_double.var = var;  stat->variant.for_double.init_val = init_val;  /* link onto SDB chain */  add_stat(sdb, stat);  /* initialize stat */  *var = init_val;  return stat;}/* create an array distribution (w/ fixed size buckets) in stat database SDB,   the array distribution has ARR_SZ buckets with BUCKET_SZ indicies in each   bucked, PF specifies the distribution components to print for optional   format FORMAT; the indicies may be optionally replaced with the strings from   IMAP, or the entire distribution can be printed with the optional   user-specified print function PRINT_FN */struct stat_stat_t *stat_reg_dist(struct stat_sdb_t *sdb,	/* stat database */	      char *name,		/* stat variable name */	      char *desc,		/* stat variable description */	      unsigned int init_val,	/* dist initial value */	      unsigned int arr_sz,	/* array size */	      unsigned int bucket_sz,	/* array bucket size */	      int pf,			/* print format, use PF_* defs */	      char *format,		/* optional variable output format */	      char **imap,		/* optional index -> string map */	      print_fn_t print_fn)	/* optional user print function */{  unsigned int i;  struct stat_stat_t *stat;  unsigned int *arr;  stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t));  if (!stat)    fatal("out of virtual memory");  stat->name = mystrdup(name);  stat->desc = mystrdup(desc);  stat->format = format ? format : NULL;  stat->sc = sc_dist;  stat->variant.for_dist.init_val = init_val;  stat->variant.for_dist.arr_sz = arr_sz;  stat->variant.for_dist.bucket_sz = bucket_sz;  stat->variant.for_dist.pf = pf;  stat->variant.for_dist.imap = imap;  stat->variant.for_dist.print_fn = print_fn;  stat->variant.for_dist.overflows = 0;  arr = (unsigned int *)calloc(arr_sz, sizeof(unsigned int));  if (!arr)    fatal("out of virtual memory");  stat->variant.for_dist.arr = arr;  /* link onto SDB chain */  add_stat(sdb, stat);  /* initialize stat */  for (i=0; i < arr_sz; i++)    arr[i] = init_val;  return stat;}/* create a sparse array distribution in stat database SDB, while the sparse   array consumes more memory per bucket than an array distribution, it can   efficiently map any number of indicies from 0 to 2^32-1, PF specifies the   distribution components to print for optional format FORMAT; the indicies   may be optionally replaced with the strings from IMAP, or the entire   distribution can be printed with the optional user-specified print function   PRINT_FN */struct stat_stat_t *stat_reg_sdist(struct stat_sdb_t *sdb,	/* stat database */	       char *name,		/* stat variable name */	       char *desc,		/* stat variable description */	       unsigned int init_val,	/* dist initial value */	       int pf,			/* print format, use PF_* defs */	       char *format,		/* optional variable output format */	       print_fn_t print_fn)	/* optional user print function */{  struct stat_stat_t *stat;  struct bucket_t **sarr;  stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t));  if (!stat)    fatal("out of virtual memory");  stat->name = mystrdup(name);  stat->desc = mystrdup(desc);  stat->format = format ? format : NULL;  stat->sc = sc_sdist;  stat->variant.for_sdist.init_val = init_val;  stat->variant.for_sdist.pf = pf;  stat->variant.for_sdist.print_fn = print_fn;  /* allocate hash table */  sarr = (struct bucket_t **)calloc(HTAB_SZ, sizeof(struct bucket_t *));  if (!sarr)    fatal("out of virtual memory");  stat->variant.for_sdist.sarr = sarr;  /* link onto SDB chain */  add_stat(sdb, stat);  return stat;}/* add NSAMPLES to array or sparse array distribution STAT */voidstat_add_samples(struct stat_stat_t *stat,/* stat database */		 unsigned int index,	/* distribution index of samples */		 int nsamples)		/* number of samples to add to dist */{  switch (stat->sc)    {    case sc_dist:      {	unsigned int i;	/* compute array index */	i = index / stat->variant.for_dist.bucket_sz;	/* check for overflow */	if (i >= stat->variant.for_dist.arr_sz)	  stat->variant.for_dist.overflows += nsamples;	else	  stat->variant.for_dist.arr[i] += nsamples;      }      break;    case sc_sdist:      {	struct bucket_t *bucket;	/* find bucket */	for (bucket = stat->variant.for_sdist.sarr[HTAB_HASH(index)];	     bucket != NULL;	     bucket = bucket->next)	  {	    if (bucket->index == index)	      break;	  }	if (!bucket)	  {	    /* add a new sample bucket */	    bucket = (struct bucket_t *)calloc(1, sizeof(struct bucket_t));	    if (!bucket)	      fatal("out of virtual memory");	    bucket->next = stat->variant.for_sdist.sarr[HTAB_HASH(index)];	    stat->variant.for_sdist.sarr[HTAB_HASH(index)] = bucket;	    bucket->index = index;	    bucket->count = stat->variant.for_sdist.init_val;	  }	bucket->count += nsamples;      }      break;    default:      panic("stat variable is not an array distribution");    }}/* add a single sample to array or sparse array distribution STAT */voidstat_add_sample(struct stat_stat_t *stat,/* stat variable */		unsigned int index)	/* index of sample */{  stat_add_samples(stat, index, 1);}/* register a double statistical formula, the formula is evaluated when the   statistic is printed, the formula expression may reference any registered   statistical variable and, in addition, the standard operators '(', ')', '+',   '-', '*', and '/', and literal (i.e., C-format decimal, hexidecimal, and   octal) constants are also supported; NOTE: all terms are immediately   converted to double values and the result is a double value, see eval.h   for more information on formulas */struct stat_stat_t *stat_reg_formula(struct stat_sdb_t *sdb,/* stat database */		 char *name,		/* stat variable name */		 char *desc,		/* stat variable description */		 char *formula,		/* formula expression */		 char *format)		/* optional variable output format */{  struct stat_stat_t *stat;  stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t));  if (!stat)    fatal("out of virtual memory");  stat->name = mystrdup(name);  stat->desc = mystrdup(desc);  stat->format = format ? format : "%12.4f";  stat->sc = sc_formula;  stat->variant.for_formula.formula = mystrdup(formula);  /* link onto SDB chain */  add_stat(sdb, stat);  return stat;}/* compare two indicies in a sparse array hash table, used by qsort() */static intcompare_fn(void *p1, void *p2){  struct bucket_t **pb1 = p1, **pb2 = p2;  /* compare indices */  if ((*pb1)->index < (*pb2)->index)    return -1;  else if ((*pb1)->index > (*pb2)->index)    return 1;  else /* ((*pb1)->index == (*pb2)->index) */    return 0;}/* print an array distribution */static voidprint_dist(struct stat_stat_t *stat,	/* stat variable */	   FILE *fd)			/* output stream */{  unsigned int i, bcount, imax, imin;  double btotal, bsum, bvar, bavg, bsqsum;  int pf = stat->variant.for_dist.pf;  /* count and sum entries */  bcount = 0; btotal = 0.0; bvar = 0.0; bsqsum = 0.0;  imax = 0; imin = UINT_MAX;  for (i=0; i<stat->variant.for_dist.arr_sz; i++)    {      bcount++;      btotal += stat->variant.for_dist.arr[i];      /* on-line variance computation, tres cool, no!?! */      bsqsum += ((double)stat->variant.for_dist.arr[i] *		 (double)stat->variant.for_dist.arr[i]);      bavg = btotal / MAX((double)bcount, 1.0);      bvar = (bsqsum - ((double)bcount * bavg * bavg)) / 	(double)(((bcount - 1) > 0) ? (bcount - 1) : 1);    }  /* print header */  fprintf(fd, "\n");  fprintf(fd, "%-22s # %s\n", stat->name, stat->desc);  fprintf(fd, "%s.array_size = %u\n",	  stat->name, stat->variant.for_dist.arr_sz);  fprintf(fd, "%s.bucket_size = %u\n",	  stat->name, stat->variant.for_dist.bucket_sz);  fprintf(fd, "%s.count = %u\n", stat->name, bcount);  fprintf(fd, "%s.total = %.0f\n", stat->name, btotal);  if (bcount > 0)    {      fprintf(fd, "%s.imin = %u\n", stat->name, 0U);      fprintf(fd, "%s.imax = %u\n", stat->name, bcount);    }  else    {      fprintf(fd, "%s.imin = %d\n", stat->name, -1);      fprintf(fd, "%s.imax = %d\n", stat->name, -1);    }  fprintf(fd, "%s.average = %8.4f\n", stat->name, btotal/MAX(bcount, 1.0));  fprintf(fd, "%s.std_dev = %8.4f\n", stat->name, sqrt(bvar));  fprintf(fd, "%s.overflows = %u\n",	  stat->name, stat->variant.for_dist.overflows);  fprintf(fd, "# pdf == prob dist fn, cdf == cumulative dist fn\n");  fprintf(fd, "# %14s ", "index");  if (pf & PF_COUNT)    fprintf(fd, "%10s ", "count");  if (pf & PF_PDF)    fprintf(fd, "%6s ", "pdf");  if (pf & PF_CDF)    fprintf(fd, "%6s ", "cdf");  fprintf(fd, "\n");  fprintf(fd, "%s.start_dist\n", stat->name);  if (bcount > 0)    {      /* print the array */      bsum = 0.0;      for (i=0; i<bcount; i++)	{	  bsum += (double)stat->variant.for_dist.arr[i];	  if (stat->variant.for_dist.print_fn)	    {	      stat->variant.for_dist.print_fn(stat,					      i,					      stat->variant.for_dist.arr[i],					      bsum,					      btotal);	    }	  else	    {	      if (stat->format == NULL)		{		  if (stat->variant.for_dist.imap)		    fprintf(fd, "%-16s ", stat->variant.for_dist.imap[i]);		  else		    fprintf(fd, "%16u ",			    i * stat->variant.for_dist.bucket_sz);		  if (pf & PF_COUNT)		    fprintf(fd, "%10u ", stat->variant.for_dist.arr[i]);		  if (pf & PF_PDF)		    fprintf(fd, "%6.2f ",			    (double)stat->variant.for_dist.arr[i] /			    MAX(btotal, 1.0) * 100.0);		  if (pf & PF_CDF)		    fprintf(fd, "%6.2f ", bsum/MAX(btotal, 1.0) * 100.0);		}	      else		{		  if (pf == (PF_COUNT|PF_PDF|PF_CDF))		    {		      if (stat->variant.for_dist.imap)		        fprintf(fd, stat->format,			        stat->variant.for_dist.imap[i],			        stat->variant.for_dist.arr[i],			        (double)stat->variant.for_dist.arr[i] /			        MAX(btotal, 1.0) * 100.0,			        bsum/MAX(btotal, 1.0) * 100.0);		      else		        fprintf(fd, stat->format,			        i * stat->variant.for_dist.bucket_sz,			        stat->variant.for_dist.arr[i],			        (double)stat->variant.for_dist.arr[i] /			        MAX(btotal, 1.0) * 100.0,			        bsum/MAX(btotal, 1.0) * 100.0);		    }		  else		    fatal("distribution format not yet implemented");

⌨️ 快捷键说明

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