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

📄 writeback.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 2 页
字号:
	    //   Recover RS_LINKs used by this instruction	    //	    for (int i = 0; i < TheISA::MaxInstDestRegs; i++) {		// blow away the consuming op list		DepLink *dep_node, *dep_node_next;		for (int q = 0; q < numIQueues; ++q) {		    for (dep_node = ROB_entry->odep_list[i][q];			 dep_node != NULL;			 dep_node = dep_node_next) {			dep_node->iq_consumer->idep_ptr[dep_node->idep_num]			    = 0;			dep_node_next = dep_node->next();			delete dep_node;		    }		}	    }	    ROB_entry->squash();	    remove_ROB_element(ROB_entry);	}    }    // FIXME: could reset functional units at squash time    //  squash any instructions in the fetch_to_decode queue    decodeQueue->squash(branch_thread);    // squash instructions and restart execution at the recover PC    fetch_squash(branch_thread);}//==========================================================================////  Branch-Recovery Event...//BranchRecoveryEvent::BranchRecoveryEvent(FullCPU *_cpu, ROBStation *rs,					 int thread,					 SpecStateList::ss_iterator sstate,					 int spec_mode)        : Event(&mainEventQueue),	  cpu(_cpu), thread_number(thread), branch_entry(rs),	  correct_PC(rs->inst->Next_PC), branch_PC(rs->inst->PC),	  dir_update(rs->inst->dir_update), staticInst(rs->inst->staticInst),	  this_spec_mode(spec_mode), spec_state(sstate){    setFlags(AutoDelete);}BranchRecoveryEvent::~BranchRecoveryEvent(){    if (spec_state.notnull())	cpu->state_list.dump(spec_state);}voidBranchRecoveryEvent::process(){    SpecExecContext *xc = cpu->thread[thread_number];    cpu->recover(branch_entry, thread_number);    //    //  If the ROB entry has not committed yet...    //    (1) mark that we have already recovered for this instruction    //    (2)    //    if (branch_entry != NULL) {	branch_entry->inst->recover_inst = false;	branch_entry->recovery_event = 0;    }    /*  Put the PC back on track  */    xc->regs.pc = correct_PC;    xc->regs.npc = correct_PC + sizeof(MachInst);    if (staticInst->isControl() && cpu->branch_pred)	cpu->branch_pred->recover(thread_number, branch_PC, &dir_update);    //    //  Only clear the pending flag if this event is the lowest    //  spec-level event    //    if (cpu->thread_info[thread_number].recovery_spec_level ==	this_spec_mode)    {	cpu->thread_info[thread_number].recovery_event_pending = false;	cpu->thread_info[thread_number].recovery_spec_level = 0;    }    //  Set the global spec_mode[] value...    xc->spec_mode = this_spec_mode;    //    //  Clear out speculative state if this was the last level of    //  misspeculation.    //    //  This CLEAR_MAP step SHOULD be unnecessary given that the    //  COPY step should always be correct.    //    cpu->state_list.release(spec_state);    //	delete spec_state;    spec_state = 0;    // don't try to delete this more than once...    if (xc->spec_mode == 0) {	/* reset use_spec_? reg maps and speculative memory state */	xc->reset_spec_state();	// since reset_spec_state() doesn't do this...	cpu->create_vector[thread_number].clear_spec();    }}const char *BranchRecoveryEvent::description(){    return "branch recovery";}//==========================================================================////  Writeback Event...////  This event is scheduled for the first (possibly ONLY) writeback//  for an instruction//WritebackEvent::WritebackEvent(FullCPU *_cpu, ROBStation *target_rs)    : Event(&_cpu->writebackEventQueue),      cpu(_cpu), rob_entry(target_rs), tag(target_rs->seq),      req(NULL){    setFlags(AutoDelete);}WritebackEvent::WritebackEvent(FullCPU *_cpu, ROBStation *target_rs,			       MemReqPtr &_req)    : Event(&_cpu->writebackEventQueue),      cpu(_cpu), rob_entry(target_rs), tag(target_rs->seq),      req(_req){    setFlags(AutoDelete);}voidWritebackEvent::trace(const char *action){    DPRINTFN("WritebackEvent for inst %d %s @ %d\n", rob_entry->seq,	     action, when());}const char *WritebackEvent::description(){    return "writeback";}////  Process a writeback event to the IQ indicated////  This event will schedule DelayedWritebackEvent's if necessary//voidWritebackEvent::process(){    //  grab this here, since writeback() may change it    bool ea_comp_inst = rob_entry->eaCompPending;    cpu->writeback_count[rob_entry->inst->thread_number]++;    if (DTRACE(Pipeline)) {	string s;	rob_entry->inst->dump(s);	DPRINTF(Pipeline, "Writeback %s\n", s);    }    //    //  Recover instructions do not generate two writeback events.    //  They write-back to all IQ's during the same cycle (ie. their    //  "home" queue is written-back late)    //    if (rob_entry->inst->recover_inst) {	unsigned wb_to_other = 0;	for (unsigned q = 0; q < cpu->numIQueues; ++q) {	    unsigned c = rob_entry->writeback(cpu, q);	    if (q != rob_entry->queue_num)		wb_to_other += c;	}	//  update stats	cpu->wb_penalized[rob_entry->inst->thread_number] += wb_to_other;    } else {	//	//  "Normal" instructions use the two-phase writeback	//	rob_entry->writeback(cpu, rob_entry->queue_num);    }    //    //  If we are writing back to more than one IQ, we have to pay a    //  penalty for all but the IQ/FU where this instruction executed    //    //  here we schedule a writeback event for the OTHER queues...    //    //  Again, note that recover instructions are DONE after this event    //    if (!ea_comp_inst) {	if (cpu->numIQueues > 1 && !rob_entry->inst->recover_inst) {	    DelayedWritebackEvent *ev =		new DelayedWritebackEvent(cpu, rob_entry);	    rob_entry->delayed_wb_event = ev;	    ev->schedule(curTick + cpu->cycles(cpu->iq_comm_latency));	} else	    rob_entry->completed = true;    }    //  indicate that this pointer is becoming invalid    rob_entry->wb_event = 0;    if (req)	req = NULL; // EGH Fix Me: do I need this}//==========================================================================////  Delayed Writeback Event...////  This event is scheduled to writeback values to clusters OTHER than the//  cluster in which the instruction executed. It is only used when//  modeling a multi-clustered machine//DelayedWritebackEvent::DelayedWritebackEvent(FullCPU *_cpu,					     ROBStation *target_rs)    : Event(&_cpu->writebackEventQueue, Delayed_Writeback_Pri),    cpu(_cpu), rob_entry(target_rs), tag(target_rs->seq){    setFlags(AutoDelete);}////  Process a delayed writeback event////  TO ALL BUT THE INDICATED Queue!!!//voidDelayedWritebackEvent::process(){    unsigned wb_to_other = 0;    //  writeback to all remote IQ's    for (unsigned c = 0; c < cpu->numIQueues; ++c)	if (rob_entry->queue_num != c)	    wb_to_other += rob_entry->writeback(cpu, c);    //  update stats    cpu->wb_penalized[rob_entry->inst->thread_number] += wb_to_other;    //  EA-Comp instructions should never get here...    rob_entry->completed = true;    //  indicate that this pointer is becoming invalid    rob_entry->delayed_wb_event = 0;}//////////////////////////////////////////////////////////////////voidFullCPU::writebackRegStats(){    using namespace Stats;    writeback_count	.init(number_of_threads)	.name(name() + ".WB:count")	.desc("cumulative count of insts written-back")	.flags(total)	;    producer_inst	.init(number_of_threads)	.name(name() + ".WB:producers")	.desc("num instructions producing a value")	.flags(total)	;    consumer_inst	.init(number_of_threads)	.name(name() + ".WB:consumers")	.desc("num instructions consuming a value")	.flags(total)	;    wb_penalized	.init(number_of_threads)	.name(name() + ".WB:penalized")	.desc("number of instrctions required to write to 'other' IQ")	.flags(total)	;    pred_wb_error_dist	.init(-10,100,1)	.name(name() + ".WB:pred_error")	.desc("error in predicted writeback times")	.flags(pdf | cdf)	;}voidFullCPU::writebackRegFormulas(){    using namespace Stats;    wb_penalized_rate	.name(name() + ".WB:penalized_rate")	.desc ("fraction of instructions written-back that wrote to 'other' IQ")	.flags(total)	;    wb_penalized_rate = wb_penalized / writeback_count;    wb_fanout	.name(name() + ".WB:fanout")	.desc("average fanout of values written-back")	.flags(total)	;    wb_fanout = producer_inst / consumer_inst;    wb_rate	.name(name() + ".WB:rate")	.desc("insts written-back per cycle")	.flags(total)	;    wb_rate = writeback_count / numCycles;}

⌨️ 快捷键说明

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