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

📄 ubuf.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif            /* statistics ---------------------------------------------------------*/      if ((max_wr_coals > 0) && (ubufptr->max_wr_coals < req->size))	ubufptr->max_wr_coals = req->size;      if ((max_rd_coals > 0) && (ubufptr->max_rd_coals < req->size))	ubufptr->max_rd_coals = req->size;      n = i + num_coals;                               /* check if rest      */      while ((n < ubufptr->entrysz) &&                 /* of entry is empty  */	     (ubufptr->entries[0]->reqs[n] == NULL))	n++;      if (n >= ubufptr->entrysz)                       /* if empty: shift    */	{	  UBUFITEM *old;	  	  if (ubufptr->entries[0]->fence)	    ubufptr->cur_reads--;	  old = ubufptr->entries[0];	  	  for (n = 1; n < ubufptr->num_entries; n++)   /* shift all entries  */	    ubufptr->entries[n-1] = ubufptr->entries[n];	  ubufptr->entries[ubufptr->num_entries-1] = old;	  /* clear old top entry  */	      	  ubufptr->num_entries--;	  StatrecUpdate(ubufptr->occ,			ubufptr->num_entries,			YS__Simtime);	}      else	ubufptr->entries[0]->busy = 1;    }}/*===========================================================================*//* determine maximum number of request that can be combined, beginning at    *//* 'start'. The size of a combined request must be a power of two, and the   *//* start address must be aligned to this size. Returns size of request.      *//*===========================================================================*/int MaxCoalesce(UBUF *ubufptr, int start){  int align, max, n;  if (ubufptr->entries[0]->reqs[start]->size < WD)    return(0);  /* count consecutive requests and sum up total request size -------------*/  for (n = start, max = 0;       (n < ubufptr->entrysz) &&	 (ubufptr->entries[0]->reqs[n] != NULL);	 max += ubufptr->entries[0]->reqs[n]->size / 4,       n += ubufptr->entries[0]->reqs[n]->size / 4);  /* reduce size of request until alignment is OK -------------------------*/  align = ubufptr->entrysz;  while ((align > 1) && ((start % align) != 0))    align /= 2;  /* reduce size further until less than or equal to uncached buffer size -*/  for (n = ubufptr->entrysz;       n > max;       n /= 2);  max = n;#ifdef UBUF_TRACE  for (n = 0; n < ubufptr->entrysz; n++)    YS__logmsg(ubufptr->nodeid,	       "%s ", ubufptr->entries[0]->reqs[n] == NULL ? "_" : "X");  YS__logmsg(ubufptr->nodeid,	     " -> %i (%i %i)\n", max >= align ? align : max, align, max);#endif    if (max >= align)    return align;  else    return max;}/*=========================================================================*//* pending uncached buffer transaction is accepted by bus interface, and   *//* ordering constraints are satisfied -> next request can be sent.         *//*=========================================================================*/void UBuffer_confirm_transaction(REQ* req){  PID2UBUF(req->node, req->src_proc)->transaction_pending = 0;}/*===========================================================================*//* UBuffer_init: creates and initializes all UBuffer modules                 *//*===========================================================================*/void UBuffer_init(void){  int      n, c, i;  UBUF    *ubufptr;  char     ubstr[40];  /*-------------------------------------------------------------------------*/  UBuffers = RSIM_CALLOC(UBUF*, ARCH_numnodes * ARCH_cpus);  if (!UBuffers)    YS__errmsg(0, "Malloc failed at %s:%i", __FILE__, __LINE__);  /*-------------------------------------------------------------------------*/  for (n = 0; n < ARCH_numnodes; n++)    for (c = 0; c < ARCH_cpus; c++)    {      ubufptr = RSIM_CALLOC(UBUF, 1);      if (!ubufptr)	YS__errmsg(n,		   "Malloc failed at %s:%i",		   __FILE__, __LINE__);      PID2UBUF(n, c) = ubufptr;      ubufptr->size        = 4;      ubufptr->entrysz     = 8;      ubufptr->combine     = 1;      ubufptr->flush       = 1;      get_parameter("ubufsize",      &ubufptr->size,    PARAM_INT);      get_parameter("ubufflush",     &ubufptr->flush,   PARAM_INT);      get_parameter("ubufentrysize", &ubufptr->entrysz, PARAM_INT);      strcpy(ubstr, "comb");      get_parameter("ubuftype", ubstr, PARAM_STRING);        if (strncasecmp(ubstr, "comb", 4) == 0)	ubufptr->combine = 1;      else if (strncasecmp(ubstr, "nocomb", 6) == 0)	ubufptr->combine = 0;      else	{	  fprintf(stderr, "Unknown uncached buffer type %s\n", ubstr);	  exit(1);	}            /*---------------------------------------------------------------------*/      ubufptr->nodeid = n;      ubufptr->procid = c;      ubufptr->above = PID2L1D(n, c);      ubufptr->below = PID2L2C(n, c);      ubufptr->num_entries = 0;      ubufptr->line_mask   = ~(ubufptr->entrysz-1);      ubufptr->entries     = RSIM_CALLOC(UBUFITEM*, ubufptr->size);      if (!ubufptr->entries)	YS__errmsg(n, "Malloc failed at %s:%i", __FILE__, __LINE__);      for (i = 0; i < ubufptr->size; i++)	{	  ubufptr->entries[i] = RSIM_CALLOC(UBUFITEM, 1);	  if (ubufptr->entries[i] == NULL)	    YS__errmsg(n, "Malloc failed at %s:%i", __FILE__, __LINE__);	  ubufptr->entries[i]->reqs = RSIM_CALLOC(REQ*, ubufptr->entrysz);	  if (ubufptr->entries[i]->reqs == NULL)	    YS__errmsg(n, "Malloc failed at %s:%i", __FILE__, __LINE__);	  memset(ubufptr->entries[i]->reqs,		 0,		 ubufptr->entrysz * sizeof(REQ*));	}      ubufptr->cur_reads = 0;      ubufptr->transaction_pending = 0;      /*---------------------------------------------------------------------*/      ubufptr->occ = NewStatrec(n,				"UBuf occupancy",				INTERVAL,				MEANS,				HIST,				ubufptr->size,				0,				ubufptr->size);      UBuffer_stat_clear(n, c);    }}/*===========================================================================*//* UBuffer_Print_params(): Print uncached buffer configuration               *//*===========================================================================*/void UBuffer_print_params(int nid, int pid){  UBUF *ubufptr = PID2UBUF(nid, pid);  YS__statmsg(nid, "Uncached Buffer Configuration\n");  YS__statmsg(nid, "  Entries: %d\t\tEntrysize: %d\n",	      ubufptr->size, ubufptr->entrysz);  YS__statmsg(nid, "  %s\t\tFlush at %i\n\n",	      ubufptr->combine ? "Combine" : "Don't Combine",	      ubufptr->flush);  YS__statmsg(nid, "\n");} /*===========================================================================*//* UBuffer_stat_report: Reports statistics of a UBuffer module               *//*===========================================================================*/ void UBuffer_stat_report(int nid, int pid){  UBUF *ubufptr = PID2UBUF(nid, pid);  YS__statmsg(nid, "Uncached Buffer Statistics\n");  YS__statmsg(nid,	      "  Stalls (Buffer Full)  : %lld cycles\n",	      ubufptr->stall_ub_full);  StatrecReport(nid, ubufptr->occ);  if (ubufptr->num_writes)    YS__statmsg(nid,		"  Total writes    : %8lld\n",		ubufptr->num_writes);    if (ubufptr->num_wr_coals)    YS__statmsg(nid,		"  Writes Coalesced: %8lld\tMax writes coalesced: %8lld bytes\n",		ubufptr->num_wr_coals,		ubufptr->max_wr_coals);  if (ubufptr->num_reads)    YS__statmsg(nid,		"  Total reads     : %8lld\tRead Latency        : %8.3f cycles\n",		ubufptr->num_reads,		ubufptr->read_latency / (double)ubufptr->num_reads);    if (ubufptr->num_rd_coals)    YS__statmsg(nid,		"  Reads Coalesced : %8lld\tMax reads coalesced : %8lld bytes\n",		ubufptr->num_rd_coals,		ubufptr->max_rd_coals);  if (ubufptr->num_barriers)    YS__statmsg(nid,		"  Memory Barriers : %8lld\teffective : %lld\n\n",		ubufptr->num_barriers,		ubufptr->num_barr_eff);    YS__statmsg(nid, "\n");}/*===========================================================================*//* UBuffer_stat_set: set statistics for completed transaction                *//*===========================================================================*/void UBuffer_stat_set(REQ *req){  UBUF *ubufptr = PID2UBUF(req->node, req->src_proc);    if (req->prcr_req_type == READ)    {      ubufptr->num_reads++;      ubufptr->read_latency += (YS__Simtime - req->issue_time);    }  if (req->prcr_req_type == WRITE)    {      ubufptr->num_writes++;    }}/*===========================================================================*//* UBuffer_stat_clear: Resets statistics collection for a UBuffer module     *//*===========================================================================*/ void UBuffer_stat_clear(int nid, int pid){  UBUF *ubufptr = PID2UBUF(nid, pid);    StatrecReset(ubufptr->occ);      ubufptr->stall_ub_full  = 0;  ubufptr->num_wr_coals   = 0;  ubufptr->max_wr_coals   = 0;  ubufptr->num_rd_coals   = 0;  ubufptr->max_rd_coals   = 0;  ubufptr->num_barriers   = 0;  ubufptr->num_barr_eff   = 0;  ubufptr->num_writes     = 0;  ubufptr->num_reads      = 0;  ubufptr->read_latency   = 0.0;}/*===========================================================================*//* Dump exhaustive debugging information                                     *//*===========================================================================*/void UBuffer_dump(int proc_id){  int nid = proc_id / ARCH_cpus;  int n, m;  UBUF *ubufptr = PID2UBUF(nid, proc_id % ARCH_cpus);  YS__logmsg(nid, "\n====== UNCACHED BUFFER ======\n");  YS__logmsg(nid, "num_entries(%d), cur_reads(%d), transaction_pending(%d)\n",	     ubufptr->num_entries, ubufptr->cur_reads,	     ubufptr->transaction_pending);    for (n = 0; n < ubufptr->num_entries; n++)    {      YS__logmsg(nid,		 "item[%i]: fence(%i), address(0x%x), type(%s), busy(%s)\n",		 n, ubufptr->entries[n]->fence, ubufptr->entries[n]->address,		 ReqName[ubufptr->entries[n]->type],		 ubufptr->entries[n]->busy);      for (m = 0; m < ubufptr->entrysz; m++)	{	  if (ubufptr->entries[n]->reqs[m] == NULL)	    continue;	  Cache_req_dump(ubufptr->entries[n]->reqs[m], 0x11, nid);	}    }}

⌨️ 快捷键说明

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