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

📄 memunit.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 4 页
字号:
	      if (inst->prd != 0)		proc->phy_int_reg_file[inst->prd] = inst->rdvalipair.a;		  	      proc->phy_int_reg_file[inst->prdp] = inst->rdvalipair.b;	      proc->intregbusy[inst->prd] = 0;	      proc->intregbusy[inst->prdp] = 0;	      proc->dist_stallq_int[inst->prd].ClearAll(proc);	      proc->dist_stallq_int[inst->prdp].ClearAll(proc);	      break;	    default:	      break;	    }	  /* Do the same for rcc too. */	  if (inst->prcc != 0)	    proc->phy_int_reg_file[inst->prcc] = inst->rccvali;	      	  proc->intregbusy[inst->prcc] = 0;	  proc->dist_stallq_int[inst->prcc].ClearAll(proc);	}    }}  /**************************************************************************//* FlushMems  : Flush the memory queues in the event of a branch mispredn *//**************************************************************************/void FlushMems(long long tag, ProcState * proc){  instance *junk;  long long tl_tag;  while (proc->ambig_st_tags.GetTail(tl_tag) &&	 tl_tag > tag)    proc->ambig_st_tags.RemoveTail();  #ifdef STORE_ORDERING  while (proc->MemQueue.NumItems())    {      proc->MemQueue.GetTail(junk);      if (junk->tag > tag)        {          proc->MemQueue.RemoveTail(); // DeleteFromTail(junk);           if (junk->mem_ready)            {              // This can happen because of non-blocking writes              // of an ordinary load that was marked ready past a done load              // that is stuck in the memunit (in which case we rely on              // the "ctr==0" requirement to stall issue)               if (simulate_ilp)                proc->ReadyUnissuedStores--;            }                    if (junk->in_memunit == 0)            {#ifdef DEBUG              if (!IsStore(junk) || IsRMW(junk))		YS__errmsg("How can tag %lld be flushed from the memunit, even after it has already been graduated?\n", junk->tag);                  // stores can come out of the memunit by being marked ready,                  // and that's ok even with NB writes#endif	      #ifdef COREFILE              if (YS__Simtime > DEBUG_TIME)                fprintf(corefile,                        "Deleting memop for tag %lld which is not in_memunit.\n",                        junk->tag);#endif              if (junk->inuse == 2)		{		  junk->inuse = 0;		  proc->meminstances.Putback(junk);		}	      else		DeleteInstance(junk, proc);            }                    junk->memprogress = 2;        }      else        break;    }   //-------------------------------------------------------------------------  // ifdef STORE_ORDERING#else    while (proc->StoreQueue.NumItems())    {      proc->StoreQueue.GetTail(junk);       if (junk->tag > tag)        {          proc->StoreQueue.RemoveTail();         // DeleteFromTail(junk);          junk->memprogress = 2;        }      else        break;    }     while (proc->LoadQueue.NumItems())    {      proc->LoadQueue.GetTail(junk);      if (junk->tag > tag)        {          proc->LoadQueue.RemoveTail();          // DeleteFromTail(junk);          junk->memprogress = 2;                 // mark this for done ones        }      else        break;    }     while (proc->st_tags.GetTail(tl_tag) && tl_tag > tag)    proc->st_tags.RemoveTail();     while (proc->rmw_tags.GetTail(tl_tag) && tl_tag > tag)    proc->rmw_tags.RemoveTail();     int mbchg = 0;  MembarInfo mb;     while (proc->membar_tags.GetTail(mb) && mb.tag > tag)    {      if (mb.SYNC)	proc->sync = 0;      proc->membar_tags.RemoveTail();      mbchg = 1; #ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)        fprintf(corefile,"Flushing out membar %lld\n", mb.tag);#endif     }    if (mbchg)    ComputeMembarQueue(proc);#endif}/*************************************************************************//* Disambiguate : Called when the address is newly generated for an      *//*              : instruction. Checks if newly disambiguated stores      *//*              : conflict with previously issued loads                  *//*************************************************************************/void Disambiguate(instance * inst, ProcState * proc){  inst->addr_ready = 1;  inst->time_addr_ready = YS__Simtime;  if (!IsStore(inst))    return;  if (!simulate_ilp)    inst->mem_ready = 1;  instance *conf;  MemQLink<instance *> *ldindex = NULL;        long long lowambig = LLONG_MAX;  proc->ambig_st_tags.Remove(inst->tag);  proc->ambig_st_tags.GetMin(lowambig);  proc->LoadQueue.GetMin(conf);  #ifndef STORE_ORDERING  while ((ldindex = proc->LoadQueue.GetNext(ldindex)) != NULL)#else  while ((ldindex = proc->MemQueue.GetNext(ldindex)) != NULL)#endif    {      conf = ldindex->d;#ifdef STORE_ORDERING      if (IsStore(conf))	continue;#endif      if (conf->tag >= inst->tag)	{	  if (conf->limbo)	    {	      if (overlap(conf, inst))		{		  conf->limbo--;		  if (spec_stores == SPEC_EXCEPT)		    {		      if (conf->exception_code == OK ||			  conf->exception_code == SERIALIZE)			{			  // mark this a soft exception			  conf->exception_code = SOFT_LIMBO;			  			  proc->active_list.flag_exception(conf->tag,							   SOFT_LIMBO);			} 		      // the following needs to be done regardless		      // of the exception code (ie, you may have		      // already had an exception caused by		      // SOFT_SL)                          		      // mark this as being "done" so that way it		      // actually graduates 		      MemQLink<instance *> *confindex = ldindex;#ifndef STORE_ORDERING		      ldindex = proc->LoadQueue.GetPrev(ldindex);		      proc->LoadQueue.Remove(confindex);#else		      ldindex = proc->MemQueue.GetPrev(ldindex);		      proc->MemQueue.Remove(confindex);#endif 		      conf->in_memunit = 0; 		      // We can bring something into the memqueue		      // right now, but we don't have to, since		      // that's definitely going to get flushed 		      proc->DoneHeap.insert(proc->curr_cycle, conf, conf->tag);		    }		  		  else if (spec_stores == SPEC_LIMBO)		    {                      conf->memprogress = 0;		      conf->vsbfwd = 0;		      proc->redos++;               // going to have to redo it		      conf->issuetime = LLONG_MAX;		    }#ifdef DEBUG		  else		    YS__errmsg(proc->proc_id / ARCH_cpus,			       "Disambiguate limbo redos should not be seen with SPEC_STALL?\n");#endif		}    // if (overlap(inst, conf))	      else if (lowambig > conf->tag)		{		  proc->unlimbos++;		  conf->limbo--;		  		  conf->memprogress = 1;		  if (!conf->limbo)		    {#ifndef STORE_ORDERING		      ldindex = proc->LoadQueue.GetPrev(ldindex);#else		      ldindex = proc->MemQueue.GetPrev(ldindex);#endif		      proc->DoneHeap.insert(proc->curr_cycle, conf, conf->tag);		    }		  PerformMemOp(conf, proc);		}	      	      else		{		  conf->limbo --;		  if (!conf->limbo)		    {		      conf->memprogress = 1;		      conf->in_memunit = 0;#ifndef STORE_ORDERING		      ldindex = proc->LoadQueue.GetPrev(ldindex);		      proc->LoadQueue.Remove(conf);#else		      ldindex = proc->MemQueue.GetPrev(ldindex);		      proc->MemQueue.Remove(conf);#endif		      proc->DoneHeap.insert(proc->curr_cycle, conf, conf->tag);		    }		}	    }	  else if ((conf->memprogress < 0) &&		   overlap(conf, inst))	    {	      proc->kills++;	      if (spec_stores == SPEC_EXCEPT)		{		  if (conf->exception_code == OK ||		      conf->exception_code == SERIALIZE)		    {		      conf->exception_code = SOFT_LIMBO;		      proc->			active_list.flag_exception(conf->tag, SOFT_LIMBO);		    }		}	      else if (spec_stores == SPEC_LIMBO)		conf->kill = 1;#ifdef DEBUG	      else		YS__errmsg(proc->proc_id / ARCH_cpus,			   "Should never get a disambiguate kill on a SPEC_STALL?\n");#endif	    }	}    }}/*#########################################################################*/#ifndef STORE_ORDERING/**************************************************************************//**************************************************************************/  int IssueBarrier(ProcState *proc){  if (!L1DQ_FULL[proc->proc_id])    {      DCache_recv_barrier(proc->proc_id);      return 1;    }  else    return 0;     // was 0 - error}void IssueLoads(ProcState*);void IssueStores(ProcState*);/* * Called every cycle by IssueQueues() -- calls IssueLoads, IssueStores, * and IssuePrefetch. Also responsible for maintaining MEMBAR status. */int IssueMem(ProcState * proc){                         instance *memop;  long long minrmw = LLONG_MAX;  proc->minload = LLONG_MAX, proc->minstore = LLONG_MAX;  /* these will leave min-values alone if nothing there */  if (proc->LoadQueue.GetMin(memop))    proc->minload = MIN(proc->minload, memop->tag);  proc->st_tags.GetMin(proc->minstore);          proc->rmw_tags.GetMin(minrmw);  proc->minload  = MIN(proc->minload, minrmw);  proc->minstore = MIN(proc->minstore, minrmw);  MembarInfo mb;  int mbchg = 0;  while (proc->membar_tags.GetMin(mb))    {      if ((!(mb.LL || mb.LS) || proc->minload > mb.tag) &&          (!(mb.SL || mb.SS) || proc->minstore > mb.tag) &&          (!mb.MEMISSUE || (proc->minstore>mb.tag && proc->minload>mb.tag)) &&	  (!mb.MEMISSUE || UBuffers[proc->proc_id]->num_entries == 0) &&	  !mb.SYNC)	{#ifdef COREFILE	  if (proc->curr_cycle > DEBUG_TIME)            fprintf(corefile, "Breaking down membar %lld\n", mb.tag);#endif	  if (!IssueBarrier(proc))	    return 0;	  mbchg = 1;	  proc->membar_tags.Remove(mb);	}      else	break;    }  if (mbchg)    {      ComputeMembarQueue(proc);      if (Speculative_Loads)	{	  // We need to go through the Load Queue and find done items.	  MemQLink<instance *> *ldindex = NULL;	  while ((ldindex = proc->LoadQueue.GetNext(ldindex)) != NULL &&		 (proc->minstore >= proc->SLtag || 		  ldindex->d->tag <= proc->SLtag) &&		 (proc->minload >= proc->LLtag || 		  ldindex->d->tag <= proc->LLtag))	    {	      instance *memop2 = ldindex->d;	      if (memop2->memprogress == 1 && !memop2->limbo)		{		  /* Get next one out first before this one is removed. */		  ldindex = proc->LoadQueue.GetPrev(ldindex);      		  /* This function will remove the access from the LoadQueue */		  PerformMemOp(memop2, proc);      		}	    }	}    }  proc->prefs = 0;     // zero prefetches so far this cycle  IssueStores(proc);  IssueLoads(proc);  if (Prefetch)     StartPrefetch(proc);  return 0;}/*************************************************************************//* ComputeMembarQueue : reset SS/LS/LL/SL tags based on membar queue     *//*************************************************************************/void ComputeMembarQueue(ProcState * proc){  // guaranteed to be out of range  proc->SStag =    proc->LStag =    proc->SLtag =    proc->LLtag =    proc->MEMISSUEtag =    -1;  MemQLink<MembarInfo> *stepper = NULL;   while ((stepper = proc->membar_tags.GetNext(stepper)) != NULL)    {      if (stepper->d.SS && proc->SStag == -1)        proc->SStag = stepper->d.tag;       if (stepper->d.LS && proc->LStag == -1)        proc->LStag = stepper->d.tag;       if (stepper->d.SL && proc->SLtag == -1)        proc->SLtag = stepper->d.tag;       if (stepper->d.LL && proc->LLtag == -1)        proc->LLtag = stepper->d.tag;       if (stepper->d.MEMISSUE && proc->MEMISSUEtag == -1)        proc->MEMISSUEtag = stepper->d.tag;      if (stepper->d.SYNC && !proc->sync)        proc->sync = 1;    }}/***************************************************************************//* ComputeMembarInfo : On a memory barrier instruction, suitably updates   *//*                   : the processor's memory-barrier implementation flags *//***************************************************************************/void ComputeMembarInfo(ProcState * proc, const MembarInfo & mb){   if (mb.SS && proc->SStag == -1)     proc->SStag = mb.tag;   if (mb.LS && proc->LStag == -1)     proc->LStag = mb.tag;   if (mb.SL && proc->SLtag == -1)     proc->SLtag = mb.tag;   if (mb.LL && proc->LLtag == -1)      proc->LLtag = mb.tag;   if (mb.MEMISSUE && proc->MEMISSUEtag == -1)      proc->MEMISSUEtag = mb.tag;}/**************************************************************************//* IssueStores : Get elements from store queue and check for dependences, *//*             : resource availability and issue it                       *//**************************************************************************/void IssueStores(ProcState * proc){

⌨️ 快捷键说明

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