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

📄 bpred.phalanx_history.c

📁 uploading the file , the system will delete the file when time expires
💻 C
📖 第 1 页 / 共 3 页
字号:
	    pred->btb.sets, pred->btb.assoc);    fprintf(stream, "ret_stack: %d entries", pred->retstack.size);    break;  case BPred2bit:    bpred_dir_config (pred->dirpred.bimod, "bimod", stream);    fprintf(stream, "btb: %d sets x %d associativity", 	    pred->btb.sets, pred->btb.assoc);    fprintf(stream, "ret_stack: %d entries", pred->retstack.size);    break;  case BPredTaken:    bpred_dir_config (pred->dirpred.bimod, "taken", stream);    break;  case BPredNotTaken:    bpred_dir_config (pred->dirpred.bimod, "nottaken", stream);    break;  default:    panic("bogus branch predictor class");  }}/* print predictor stats */voidbpred_stats(struct bpred_t *pred,	/* branch predictor instance */	    FILE *stream)		/* output stream */{  fprintf(stream, "pred: addr-prediction rate = %f\n",	  (double)pred->addr_hits/(double)(pred->addr_hits+pred->misses));  fprintf(stream, "pred: dir-prediction rate = %f\n",	  (double)pred->dir_hits/(double)(pred->dir_hits+pred->misses));}/* register branch predictor stats */voidbpred_reg_stats(struct bpred_t *pred,	/* branch predictor instance */		struct stat_sdb_t *sdb)	/* stats database */{  char buf[512], buf1[512], *name;  /* get a name for this predictor */  switch (pred->class)    {    case BPredPhalanx:      name = "bpred_phalanx";      break;    case BPredComb:      name = "bpred_comb";      break;    case BPred2Level:      name = "bpred_2lev";      break;    case BPred2bit:      name = "bpred_bimod";      break;    case BPredTaken:      name = "bpred_taken";      break;    case BPredNotTaken:      name = "bpred_nottaken";      break;    default:      panic("bogus branch predictor class");    }  sprintf(buf, "%s.lookups", name);  stat_reg_counter(sdb, buf, "total number of bpred lookups",		   &pred->lookups, 0, NULL);  sprintf(buf, "%s.updates", name);  sprintf(buf1, "%s.dir_hits + %s.misses", name, name);  stat_reg_formula(sdb, buf, "total number of updates", buf1, "%12.0f");  sprintf(buf, "%s.addr_hits", name);  stat_reg_counter(sdb, buf, "total number of address-predicted hits", 		   &pred->addr_hits, 0, NULL);  sprintf(buf, "%s.dir_hits", name);  stat_reg_counter(sdb, buf, 		   "total number of direction-predicted hits "		   "(includes addr-hits)", 		   &pred->dir_hits, 0, NULL);  if (pred->class == BPredComb)    {      sprintf(buf, "%s.used_bimod", name);      stat_reg_counter(sdb, buf, 		       "total number of bimodal predictions used", 		       &pred->used_bimod, 0, NULL);      sprintf(buf, "%s.used_2lev", name);      stat_reg_counter(sdb, buf, 		       "total number of 2-level predictions used", 		       &pred->used_2lev, 0, NULL);    }  sprintf(buf, "%s.misses", name);  stat_reg_counter(sdb, buf, "total number of misses", &pred->misses, 0, NULL);  sprintf(buf, "%s.jr_hits", name);  stat_reg_counter(sdb, buf,		   "total number of address-predicted hits for JR's",		   &pred->jr_hits, 0, NULL);  sprintf(buf, "%s.jr_seen", name);  stat_reg_counter(sdb, buf,		   "total number of JR's seen",		   &pred->jr_seen, 0, NULL);  sprintf(buf, "%s.jr_non_ras_hits.PP", name);  stat_reg_counter(sdb, buf,		   "total number of address-predicted hits for non-RAS JR's",		   &pred->jr_non_ras_hits, 0, NULL);  sprintf(buf, "%s.jr_non_ras_seen.PP", name);  stat_reg_counter(sdb, buf,		   "total number of non-RAS JR's seen",		   &pred->jr_non_ras_seen, 0, NULL);  sprintf(buf, "%s.bpred_addr_rate", name);  sprintf(buf1, "%s.addr_hits / %s.updates", name, name);  stat_reg_formula(sdb, buf,		   "branch address-prediction rate (i.e., addr-hits/updates)",		   buf1, "%9.4f");  sprintf(buf, "%s.bpred_dir_rate", name);  sprintf(buf1, "%s.dir_hits / %s.updates", name, name);  stat_reg_formula(sdb, buf,		  "branch direction-prediction rate (i.e., all-hits/updates)",		  buf1, "%9.4f");  sprintf(buf, "%s.bpred_jr_rate", name);  sprintf(buf1, "%s.jr_hits / %s.jr_seen", name, name);  stat_reg_formula(sdb, buf,		  "JR address-prediction rate (i.e., JR addr-hits/JRs seen)",		  buf1, "%9.4f");  sprintf(buf, "%s.bpred_jr_non_ras_rate.PP", name);  sprintf(buf1, "%s.jr_non_ras_hits.PP / %s.jr_non_ras_seen.PP", name, name);  stat_reg_formula(sdb, buf,		   "non-RAS JR addr-pred rate (ie, non-RAS JR hits/JRs seen)",		   buf1, "%9.4f");  sprintf(buf, "%s.retstack_pushes", name);  stat_reg_counter(sdb, buf,		   "total number of address pushed onto ret-addr stack",		   &pred->retstack_pushes, 0, NULL);  sprintf(buf, "%s.retstack_pops", name);  stat_reg_counter(sdb, buf,		   "total number of address popped off of ret-addr stack",		   &pred->retstack_pops, 0, NULL);  sprintf(buf, "%s.used_ras.PP", name);  stat_reg_counter(sdb, buf,		   "total number of RAS predictions used",		   &pred->used_ras, 0, NULL);  sprintf(buf, "%s.ras_hits.PP", name);  stat_reg_counter(sdb, buf,		   "total number of RAS hits",		   &pred->ras_hits, 0, NULL);  sprintf(buf, "%s.ras_rate.PP", name);  sprintf(buf1, "%s.ras_hits.PP / %s.used_ras.PP", name, name);  stat_reg_formula(sdb, buf,		   "RAS prediction rate (i.e., RAS hits/used RAS)",		   buf1, "%9.4f");}// zero all the prediction stats, for whatever reasonvoidbpred_after_priming(struct bpred_t *bpred){  if (bpred == NULL)    return;  bpred->lookups = 0;  bpred->addr_hits = 0;  bpred->dir_hits = 0;  bpred->used_ras = 0;  bpred->used_bimod = 0;  bpred->used_2lev = 0;  bpred->jr_hits = 0;  bpred->jr_seen = 0;  bpred->misses = 0;  bpred->retstack_pops = 0;  bpred->retstack_pushes = 0;  bpred->ras_hits = 0;}// this hash function is used by the bimodal predictor to select locations for BTB entries#define BIMOD_HASH(PRED, ADDR)						\  ((((ADDR) >> 19) ^ ((ADDR) >> MD_BR_SHIFT)) & ((PRED)->config.bimod.size-1))    /* was: ((baddr >> 16) ^ baddr) & (pred->dirpred.bimod.size-1) */// For stateful predictors, returns a pointer (the char *) to the bits// that are being used to predict the branch...basically returns a pointer// to the 2-bit saturating up/down counter used by the predictor for the// branch at address "baddr"// NOTE: NO WORK MUST BE DONE HERE FOR PHALANXchar *						/* pointer to counter */bpred_dir_lookup(struct bpred_dir_t *pred_dir,	/* branch dir predictor inst */		 md_addr_t baddr)		/* branch address */{  unsigned char *p = NULL;  /* Except for jumps, get a pointer to direction-prediction bits */  switch (pred_dir->class) {    case BPred2Level:      {	int l1index, l2index;        /* traverse 2-level tables */        l1index = (baddr >> MD_BR_SHIFT) & (pred_dir->config.two.l1size - 1);        l2index = pred_dir->config.two.shiftregs[l1index];        if (pred_dir->config.two.xor)	  {#if 1	    /* this L2 index computation is more "compatible" to McFarling's	       verison of it, i.e., if the PC xor address component is only	       part of the index, take the lower order address bits for the	       other part of the index, rather than the higher order ones */	    l2index = (((l2index ^ (baddr >> MD_BR_SHIFT))			& ((1 << pred_dir->config.two.shift_width) - 1))		       | ((baddr >> MD_BR_SHIFT)			  << pred_dir->config.two.shift_width));#else	    l2index = l2index ^ (baddr >> MD_BR_SHIFT);#endif	  }	else	  {	    l2index =	      l2index		| ((baddr >> MD_BR_SHIFT) << pred_dir->config.two.shift_width);	  }        l2index = l2index & (pred_dir->config.two.l2size - 1);        /* get a pointer to prediction state information */        p = &pred_dir->config.two.l2table[l2index];      }      break;    case BPred2bit:      p = &pred_dir->config.bimod.table[BIMOD_HASH(pred_dir, baddr)];      break;    case BPredTaken:    case BPredNotTaken:      break;    default:      panic("bogus branch direction predictor class");    }  return (char *)p;}/* probe a predictor for a next fetch address, the predictor is probed   with branch address BADDR, the branch target is BTARGET (used for   static predictors), and OP is the instruction opcode (used to simulate   predecode bits; a pointer to the predictor state entry (or null for jumps)   is returned in *DIR_UPDATE_PTR (used for updating predictor state),   and the non-speculative top-of-stack is returned in stack_recover_idx    (used for recovering ret-addr stack after mis-predict).  */md_addr_t				/* predicted branch target addr */bpred_lookup(struct bpred_t *pred,	/* branch predictor instance */	     md_addr_t baddr,		/* branch address */	     md_addr_t btarget,		/* branch target if taken */	     enum md_opcode op,		/* opcode of instruction */	     int is_call,		/* non-zero if inst is fn call */	     int is_return,		/* non-zero if inst is fn return */	     struct bpred_update_t *dir_update_ptr, /* pred state pointer */	     int *stack_recover_idx)	/* Non-speculative top-of-stack;					 * used on mispredict recovery */{  // if this is a phalanx predictor, ignore everything in this  // procedure and simply call bpred_lookup for all child predictors  if(pred->class==BPredPhalanx) {    /* if this is not a branch, return not-taken */    if (!(MD_OP_FLAGS(op) & F_CTRL))      return 0;    // there is a policy decision to be made here	// the current policy is HISTORY NO-STICKY    // do statistic-maintenance operations here    pred->lookups++;        // if this is a return, record that statistic    if (is_return && pred->retstack.size)      {        pred->retstack_pops++;      }#ifndef RAS_BUG_COMPATIBLE    // if this is a call, record a restack push stat    if (is_call && pred->retstack.size)      {        pred->retstack_pushes++;      }#endif /* !RAS_BUG_COMPATIBLE */    // if this is not a conditonal branch, rely on the GSHARE    if (!((MD_OP_FLAGS(op) & (F_CTRL|F_UNCOND)) != (F_CTRL|F_UNCOND))) {       // this is not a combinational branch       if(GSHARE_ENABLE)       return bpred_lookup(pred->phalanx.gshare,baddr,btarget,op,is_call,                           is_return,dir_update_ptr,stack_recover_idx);       if(GAG_ENABLE)       return bpred_lookup(pred->phalanx.gag,baddr,btarget,op,is_call,                           is_return,dir_update_ptr,stack_recover_idx);       if(PAG_ENABLE)       return bpred_lookup(pred->phalanx.pag,baddr,btarget,op,is_call,                           is_return,dir_update_ptr,stack_recover_idx);       if(PAP_ENABLE)       return bpred_lookup(pred->phalanx.pap,baddr,btarget,op,is_call,                           is_return,dir_update_ptr,stack_recover_idx);       if(BIMOD_ENABLE)       return bpred_lookup(pred->phalanx.bimod,baddr,btarget,op,is_call,                           is_return,dir_update_ptr,stack_recover_idx);           }	// call selectPred() to figure out which predictor to use	int predictor = selectPred(pred);   struct bpred_t * nth;   int cfp = -1;   cfp += GAG_ENABLE;   if(cfp==predictor) nth = pred->phalanx.gag;   else {     cfp += PAG_ENABLE;     if(cfp==predictor) nth = pred->phalanx.pag;     else {       cfp += PAP_ENABLE;       if(cfp==predictor) nth = pred->phalanx.pap;       else {         cfp += GSHARE_ENABLE;         if(cfp==predictor) nth = pred->phalanx.gshare;         else nth=pred->phalanx.bimod;       }     }   }    // call bpred_lookup for the nth predictor   return bpred_lookup(nth,                       baddr,btarget,                       op,is_call,is_return,							dir_update_ptr,							stack_recover_idx);  } // else this is not a phalanx predictor, do the normal thing  // pbtb is a pointer to a branch table buffer entry  struct bpred_btb_ent_t *pbtb = NULL;  int index, i;  if (!dir_update_ptr)    panic("no bpred update record");  /* if this is not a branch, return not-taken */  if (!(MD_OP_FLAGS(op) & F_CTRL))    return 0;  pred->lookups++;  dir_update_ptr->dir.ras = FALSE;  dir_update_ptr->pdir1 = NULL;  dir_update_ptr->pdir2 = NULL;  dir_update_ptr->pmeta = NULL;  /* Except for jumps, get a pointer to direction-prediction bits */  switch (pred->class) {    case BPredComb:      if ((MD_OP_FLAGS(op) & (F_CTRL|F_UNCOND)) != (F_CTRL|F_UNCOND))	// if this is a conditional branch	{	  char *bimod, *twolev, *meta;	  bimod = bpred_dir_lookup (pred->dirpred.bimod, baddr);	  twolev = bpred_dir_lookup (pred->dirpred.twolev, baddr);	  meta = bpred_dir_lookup (pred->dirpred.meta, baddr);	  dir_update_ptr->pmeta = meta;	  dir_update_ptr->dir.meta  = (*meta >= 2);	  dir_update_ptr->dir.bimod = (*bimod >= 2);	  dir_update_ptr->dir.twolev  = (*twolev >= 2);	  if (*meta >= 2)	    {	      dir_update_ptr->pdir1 = twolev;	      dir_update_ptr->pdir2 = bimod;	    }	  else	    {	      dir_update_ptr->pdir1 = bimod;	      dir_update_ptr->pdir2 = twolev;	    }	}      break;    case BPred2Level:      if ((MD_OP_FLAGS(op) & (F_CTRL|F_UNCOND)) != (F_CTRL|F_UNCOND))	// if this is a conditional branch	{	  dir_update_ptr->pdir1 =	    bpred_dir_lookup (pred->dirpred.twolev, baddr);	}      break;    case BPred2bit:      if ((MD_OP_FLAGS(op) & (F_CTRL|F_UNCOND)) != (F_CTRL|F_UNCOND))	// if this is a conditional branch	{	  dir_update_ptr->pdir1 =	    bpred_dir_lookup (pred->dirpred.bimod, baddr);	}      break;    case BPredTaken:      if(PRINT_PREDS==0) {        fprintf(outfile,"PRED: ALWAYS TAKEN  for address %i\tis T\tto%i\n",(int)baddr,(int)btarget);	fflush(outfile);      }            return btarget;    case BPredNotTaken:      if ((MD_OP_FLAGS(op) & (F_CTRL|F_UNCOND)) != (F_CTRL|F_UNCOND))	// if this is a conditional branch	{          if(PRINT_PREDS==0) {            fprintf(outfile,"PRED: ALWAYS NOTTAKEN  for address %i\tis NT\tto%i\n",(int)baddr,(int)baddr+sizeof(md_inst_t));            fflush(outfile);          }	  return baddr + sizeof(md_inst_t);	}      else	// this is not a conditional branch	{          if(PRINT_PREDS==0) {            fprintf(outfile,"PRED: ALWAYS NOTTAKEN  for address %i\tis T\tto%i\n",(int)baddr,(int)btarget);            fflush(outfile);          }	  	  	  return btarget;	}    default:      panic("bogus predictor class");  }// it is expected that only Statefule predictors reach the rest of the// code in this procedure  /*   * We have a stateful predictor, and have gotten a pointer into the   * direction predictor (except for jumps, for which the ptr is null)   */

⌨️ 快捷键说明

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