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

📄 l1d_cache.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		    captr->procid);      /*       * Collect statistics if the mainreq is a late prefetch.       */      if (pmshr->demand > 0)	{	  if (pmshr->mainreq->prefetch == 1)            captr->pstats->sl1.lateness += YS__Simtime - pmshr->demand;	  else if (pmshr->mainreq->prefetch == 4)            captr->pstats->l1dp.lateness += YS__Simtime - pmshr->demand;	  pmshr->demand = -1;	}      cline     = pmshr->cline;      misscache = pmshr->misscache;      req->wrb_req = 0;      if (misscache == 0)     /* line present in cache -- upgrade reply */	 cline->state = PR_DY;      else	{ /* line not present in cache */	  if (misscache == 1)	    { 	      /* "present" miss -- COHE miss */	      Cache_pmiss_update(captr, req, cline->index, pmshr->only_prefs);	      CCD_InsertNewLine(captr->ccd, ADDR2BNUM1D(req->paddr));         	      req->miss_type1 = CACHE_MISS_COHE;	    }	  else	    {	      /* total miss: find a victim and updates ages */	      if (!Cache_miss_update(captr, req, &cline, pmshr->only_prefs))		YS__errmsg(captr->nodeid,			   "L1WT should never see a NO_REPLACE");	      /* We should determine COLD/CAP/CONF */	      ccdres = CCD_InsertNewLine(captr->ccd, ADDR2BNUM1D(req->paddr));	      req->miss_type1 = req->line_cold ? CACHE_MISS_COLD : ccdres;	      pmshr->cline = cline;	    }	  if (cline->state == SH_CL)	    captr->pstats->shcl_victims1d++;	  else if (cline->state == PR_CL)	    captr->pstats->prcl_victims1d++;	  else if (cline->state == PR_DY)	    {	      if (cparam.L1D_writeback)		{		  req->wrb_req = Cache_make_req(captr, cline, WBACK);		  req->wrb_req->type = REQUEST;		}	      captr->pstats->prdy_victims1d++;	    }	  /* 	   * Now fill in the information for the new line 	   */	  cline->tag   = req->paddr >> captr->tag_shift;	  cline->vaddr = req->vaddr & block_mask1d;	  if (pmshr->has_writes)	    cline->state = PR_DY;	  else	    cline->state = (req->req_type == REPLY_SH) ? SH_CL : PR_CL;	}      req->progress = 1;    }  if (req->progress == 1)    {      if (req->wrb_req)	{	  LinkQueue *lq = &(captr->l2_partner->request_queue);	  if (lqueue_full(lq))            return 0;	  else	    {	      lqueue_add(lq, req->wrb_req, captr->nodeid);	      captr->l2_partner->inq_empty = 0;	    }	}      req->progress = 2;    }    /*    * Now, resolve all requests coalesced into the MSHR in question. Send    * them back to the processor for possible further handling. And if any   * flush/purge transaction is pending, activate it.   */  pmshr = req->l1mshr;  L1DCache_uncoalesce_mshr(captr, pmshr);  if (pmshr->pend_opers && pmshr->cline->state != INVALID)    {      if (pmshr->cline->pref == 1)	captr->pstats->sl1.useless++;      else if (pmshr->cline->pref == 4)	captr->pstats->l1dp.useless++;      pmshr->cline->state = INVALID;      pmshr->cline->tag = -1;    }  /*     * free up the MSHR, or release all coalesced requests.    */  Cache_free_mshr(captr, pmshr);    return 1;}/*============================================================================= * Uncoalesce each request coalesced in the specified MSHR. */int L1DCache_uncoalesce_mshr(CACHE *captr, MSHR *pmshr){  HIT_TYPE  hit_type = pmshr->mainreq->hit_type;  int       latepf   = (pmshr->demand > 0.0);  int       i;  /*   * If this MSHR had a late prefetch, set prefetched_late field to allow   * system to count every access coalesced into the MSHR as part of "late PF"   * time in statistics. Is this reasonable?   */  pmshr->mainreq->prefetched_late = latepf;  if (pmshr->mainreq->prefetch == 4)    {      if (!pmshr->mainreq->cohe_count)	YS__PoolReturnObj(&YS__ReqPool, pmshr->mainreq);    }  else    Cache_global_perform(captr, pmshr->mainreq, 1);  for (i = 0; i < pmshr->counter; i++)    {      REQ *req = pmshr->coal_req[i];      /*       * In addition to latepf, also set hit_type of each coalesced REQUEST       * to be L1HIT. This allows all of these times to be counted as the       * appropriate component of execution time.       */      req->hit_type = L1DHIT;      req->prefetched_late = latepf;      if (req->prefetch == 4)	YS__errmsg(captr->nodeid,		   "L1Cache_uncoalesce_msrh: coalesced L1 prefetch");            Cache_global_perform(captr, req, 1);    }  return 0;}/*============================================================================= * L1ProcessTagCohe: simulates coherence requests or invalidation * request to the L1 cache. An invalidation request is sent by the L2 * when a miss victim is casted out of L2 cache in order to ensure the  * "inclusion property". */static int L1DProcessTagCohe(CACHE * captr, REQ * req){  cline_t *cline;  int      i, misscache;  unsigned paddr;  unsigned vaddr;  unsigned eaddr;  if (cparam.L1D_perfect)    req->progress = 1;  if (req->progress == 0)    {      paddr = req->paddr & block_mask2;      vaddr = req->vaddr & block_mask2;      eaddr = paddr + ARCH_linesz2;      for (; paddr < eaddr; paddr += ARCH_linesz1d, vaddr += ARCH_linesz1d)	{	  misscache = Cache_search(captr, vaddr, paddr, &cline);       	  if (misscache == 0)	    {  /* line in cache */	      if (req->req_type == INVALIDATE)		{		  if (captr->gid == req->src_proc)		    {		      /* 		       * It's actually an invalidation request. Reset the tag		       * so it won't be taken as a victim of coherence check.		       */		      cline->tag = -1;		    }		  if (cline->state == PR_DY)		    req->wb_count++;		  cline->state = INVALID;		  if (cline->pref == 1)		    captr->pstats->sl1.useless++;		  else if (cline->pref == 4)		    captr->pstats->l1dp.useless++;		  /* 		   * Invalidated; check outstanding speculative loads. 		   */		  if (Speculative_Loads)      		    SpecLoadBufCohe(captr->procid, paddr, SLB_Cohe);		}	      else		cline->state = SH_CL;	    }	}      req->progress = 1;    }  if (cparam.L1D_writeback)    return L2ProcessL1Reply(captr->l2_partner, req);  else    {      if (!req->cohe_count)	YS__PoolReturnObj(&YS__ReqPool, req);      return 1;    }}/*============================================================================= * Start an L1-initiated prefetch. If L1Q is full, drop the prefetch. * Note that prefetch can not cross page boudary and no prefetch for * non-cacheable address. */static void L1DCache_start_prefetch(CACHE *captr, REQ *req){  REQ *newreq;  unsigned newpaddr = req->paddr + captr->linesz;  if (!SAMEPAGE(req->paddr, newpaddr) ||      tlb_uncached(req->memattributes))    return;  captr->pstats->l1dp.total++;  if (L1DQ_FULL[captr->gid])    {      captr->pstats->l1dp.dropped++;      return;    }  /*   * General information   */  newreq = (REQ *) YS__PoolGetObj(&YS__ReqPool);    newreq->type          = REQUEST;  newreq->req_type      = READ;  newreq->prefetch      = 4;  newreq->node          = captr->nodeid;  newreq->src_proc      = captr->procid;  newreq->prcr_req_type = req->prcr_req_type;  newreq->paddr         = newpaddr;  newreq->vaddr         = req->vaddr + captr->linesz;  newreq->ifetch        = 0;  newreq->l1mshr        = 0;  newreq->l2mshr        = 0;  newreq->memattributes = req->memattributes;  newreq->line_cold     = 0;  /*   * for statistics   */  newreq->issue_time    = YS__Simtime;  newreq->hit_type      = UNKHIT;  newreq->line_cold     = 0;    /*   * Add it to REQUEST input queue of L1 cache, which must then know that    * there is something on its input queue so as to be activated by    * cycle-by-cycle simulator. If this access fills up the port, the    * L1Q_FULL variable is set so that the processor does not issue any    * more memory references until the port clears up.    */  lqueue_add(&(captr->request_queue), newreq, captr->nodeid);  captr->inq_empty  = 0;  L1DQ_FULL[captr->gid] = lqueue_full(&(captr->request_queue));}#if 0void L1ProcessTagPipe(CACHE *captr, int pipenum){  Pipeline *pipe = captr->tag_pipe[pipenum];  int       ctr  = 0;  REQ       *req;    while (1)    {      GetPipeElt(req, pipe);      if (req == 0)	break;      if (L1ProcessTagReq(captr, req) == 1)	{	  ClearPipeElt(pipe);	  captr->num_in_pipes--;	}      else	ctr++;    }}/* * L1ProcessTagReq: simulates accesses to the L1 cache. * Its behavior depends on the type of message (i.e. type) received * Returns 0 on failure; 1 on success. */static int L1ProcessTagReq(CACHE * captr, REQ * req){  switch (req->type)    {    case REQUEST:      return L1ProcessTagRequest(captr, req);    case REPLY:      return L1ProcessTagReply(captr, req);    case COHE:      return L1ProcessTagCohe(captr, req);    case COHE_REPLY:      YS__errmsg("L1 cache should not get a COHE_REPLY!");    }  YS__errmsg("Unreachable code in L1ProcessTagReq()!");  return 0;}/* * Macro that processes input queues of L1 cache. Used by L1CacheInSim. */#define ProcessInputQueue(lq, pipenum)                     	\        while (req = (REQ *) lqueue_head(lq)) {                 \           if (AddToPipe(captr->tag_pipe[pipenum], req)) {      \              req->progress = 0;                                \              lqueue_remove(lq, next, REQ *);                   \              captr->num_in_pipes++;                            \           }                                                    \           else {                                               \              nothing_on_ports = 0;                             \              break;                                            \           }                                                    \        }/* * Macro that processes pipelines of L1 cache. Used by L1CacheOutSim. */#define ProcessPipeline(pline, pfunc)           \        pipe = pline;                           \        ctr  = 0;                               \        while (1) {                             \           GetPipeElt(req, pipe, ctr);          \           if (req == 0)                        \              break;                            \           if (pfunc(captr, req)) {             \              ClearPipeElt(pipe, ctr);          \              captr->num_in_pipes--;            \           }                                    \           else                                 \              ctr++;                            \        }#endif

⌨️ 快捷键说明

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