From 0b29c2d057d2d6f4f8b9b7853da91bcb283e805c Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:28:59 -0500 Subject: inorder: ctxt switch stats - m5 line enforcement on use_def.cc,hh --- src/cpu/inorder/cpu.cc | 26 +++- src/cpu/inorder/cpu.hh | 5 + src/cpu/inorder/pipeline_stage.cc | 3 + src/cpu/inorder/resources/graduation_unit.hh | 2 - src/cpu/inorder/resources/use_def.cc | 216 +++++++++++++++++++-------- src/cpu/inorder/resources/use_def.hh | 12 +- 6 files changed, 196 insertions(+), 68 deletions(-) (limited to 'src/cpu/inorder') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 4cc9b9f22..b69fe2e3b 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -189,7 +189,8 @@ InOrderCPU::InOrderCPU(Params *params) #endif // DEBUG switchCount(0), deferRegistration(false/*params->deferRegistration*/), - stageTracing(params->stageTracing) + stageTracing(params->stageTracing), + instsPerSwitch(0) { ThreadID active_threads; cpu_params = params; @@ -352,6 +353,15 @@ InOrderCPU::regStats() } /* Register any of the InOrderCPU's stats here.*/ + instsPerCtxtSwitch + .name(name() + ".instsPerContextSwitch") + .desc("Instructions Committed Per Context Switch") + .prereq(instsPerCtxtSwitch); + + numCtxtSwitches + .name(name() + ".contextSwitches") + .desc("Number of context switches"); + timesIdled .name(name() + ".timesIdled") .desc("Number of times that the entire CPU went into an idle state and" @@ -719,6 +729,8 @@ InOrderCPU::activateThread(ThreadID tid) tcBase(tid)->setStatus(ThreadContext::Active); wakeCPU(); + + numCtxtSwitches++; } } @@ -1056,6 +1068,15 @@ InOrderCPU::addInst(DynInstPtr &inst) return --(instList[tid].end()); } +void +InOrderCPU::updateContextSwitchStats() +{ + // Set Average Stat Here, then reset to 0 + instsPerCtxtSwitch = instsPerSwitch; + instsPerSwitch = 0; +} + + void InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) { @@ -1086,6 +1107,9 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) inst->traceData = NULL; } + // Increment active thread's instruction count + instsPerSwitch++; + // Increment thread-state's instruction count thread[tid]->numInst++; diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 70013c0f5..6f1f3ee3f 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -707,6 +707,11 @@ class InOrderCPU : public BaseCPU /** The cycle that the CPU was last running, used for statistics. */ Tick lastRunningCycle; + void updateContextSwitchStats(); + unsigned instsPerSwitch; + Stats::Average instsPerCtxtSwitch; + Stats::Scalar numCtxtSwitches; + /** Update Thread , used for statistic purposes*/ inline void tickThreadStats(); diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index e601edfcc..550952947 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -570,6 +570,9 @@ PipelineStage::activateThread(ThreadID tid) // Clear switchout buffer switchedOutBuffer[tid] = NULL; switchedOutValid[tid] = false; + + // Update any CPU stats based off context switches + cpu->updateContextSwitchStats(); } } diff --git a/src/cpu/inorder/resources/graduation_unit.hh b/src/cpu/inorder/resources/graduation_unit.hh index ad222b119..7f0db98d0 100644 --- a/src/cpu/inorder/resources/graduation_unit.hh +++ b/src/cpu/inorder/resources/graduation_unit.hh @@ -63,8 +63,6 @@ class GraduationUnit : public Resource { bool *nonSpecInstActive[ThePipeline::MaxThreads]; InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads]; - - /** @todo: Add Resource Stats Here */ }; #endif //__CPU_INORDER_GRAD_UNIT_HH__ diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc index 36392d054..a4f3a0d21 100644 --- a/src/cpu/inorder/resources/use_def.cc +++ b/src/cpu/inorder/resources/use_def.cc @@ -59,6 +59,17 @@ UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width, } +void +UseDefUnit::regStats() +{ + uniqueRegsPerSwitch + .name(name() + ".uniqueRegsPerSwitch") + .desc("Number of Unique Registers Needed Per Context Switch") + .prereq(uniqueRegsPerSwitch); + + Resource::regStats(); +} + ResReqPtr UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx, int slot_num, unsigned cmd) @@ -75,7 +86,8 @@ UseDefUnit::findRequest(DynInstPtr inst) map::iterator map_end = reqMap.end(); while (map_it != map_end) { - UseDefRequest* ud_req = dynamic_cast((*map_it).second); + UseDefRequest* ud_req = + dynamic_cast((*map_it).second); assert(ud_req); if (ud_req && @@ -107,9 +119,9 @@ UseDefUnit::execute(int slot_idx) // in the pipeline then stall instructions here if (*nonSpecInstActive[tid] == true && seq_num > *nonSpecSeqNum[tid]) { - DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because there is " - "non-speculative instruction [sn:%i] has not graduated.\n", - tid, seq_num, *nonSpecSeqNum[tid]); + DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because" + "there is non-speculative instruction [sn:%i] has not " + "graduated.\n", tid, seq_num, *nonSpecSeqNum[tid]); return; } else if (inst->isNonSpeculative()) { *nonSpecInstActive[tid] = true; @@ -121,89 +133,129 @@ UseDefUnit::execute(int slot_idx) case ReadSrcReg: { int reg_idx = inst->_srcRegIdx[ud_idx]; - - DPRINTF(InOrderUseDef, "[tid:%i]: Attempting to read source register idx %i (reg #%i).\n", + + DPRINTF(InOrderUseDef, "[tid:%i]: Attempting to read source " + "register idx %i (reg #%i).\n", tid, ud_idx, reg_idx); - // Ask register dependency map if it is OK to read from Arch. Reg. File + // Ask register dependency map if it is OK to read from Arch. + // Reg. File if (regDepMap[tid]->canRead(reg_idx, inst)) { + + uniqueRegMap[reg_idx] = true; + if (inst->seqNum <= outReadSeqNum[tid]) { if (reg_idx < FP_Base_DepTag) { - DPRINTF(InOrderUseDef, "[tid:%i]: Reading Int Reg %i from Register File:%i.\n", - tid, reg_idx, cpu->readIntReg(reg_idx,inst->readTid())); + DPRINTF(InOrderUseDef, "[tid:%i]: Reading Int Reg %i" + "from Register File:%i.\n", + tid, + reg_idx, + cpu->readIntReg(reg_idx,inst->readTid())); inst->setIntSrc(ud_idx, - cpu->readIntReg(reg_idx,inst->readTid())); + cpu->readIntReg(reg_idx, + inst->readTid())); } else if (reg_idx < Ctrl_Base_DepTag) { reg_idx -= FP_Base_DepTag; - DPRINTF(InOrderUseDef, "[tid:%i]: Reading Float Reg %i from Register File:%x (%08f).\n", + DPRINTF(InOrderUseDef, "[tid:%i]: Reading Float Reg %i" + "from Register File:%x (%08f).\n", tid, reg_idx, - cpu->readFloatRegBits(reg_idx, inst->readTid()), - cpu->readFloatReg(reg_idx, inst->readTid())); + cpu->readFloatRegBits(reg_idx, + inst->readTid()), + cpu->readFloatReg(reg_idx, + inst->readTid())); inst->setFloatSrc(ud_idx, - cpu->readFloatReg(reg_idx, inst->readTid())); + cpu->readFloatReg(reg_idx, + inst->readTid())); } else { reg_idx -= Ctrl_Base_DepTag; - DPRINTF(InOrderUseDef, "[tid:%i]: Reading Misc Reg %i from Register File:%i.\n", - tid, reg_idx, cpu->readMiscReg(reg_idx, inst->readTid())); + DPRINTF(InOrderUseDef, "[tid:%i]: Reading Misc Reg %i " + "from Register File:%i.\n", + tid, + reg_idx, + cpu->readMiscReg(reg_idx, + inst->readTid())); inst->setIntSrc(ud_idx, - cpu->readMiscReg(reg_idx, inst->readTid())); + cpu->readMiscReg(reg_idx, + inst->readTid())); } outReadSeqNum[tid] = maxSeqNum; ud_req->done(); } else { - DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because of [sn:%i] hasnt read it's" - " registers yet.\n", tid, outReadSeqNum[tid]); - DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for [sn:%i] to write\n", + DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because " + "of [sn:%i] hasnt read it's registers yet.\n", + tid, outReadSeqNum[tid]); + DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for " + "[sn:%i] to write\n", tid, outReadSeqNum[tid]); } } else { // Look for forwarding opportunities - DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx, ud_idx, inst); + DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx, + ud_idx, + inst); if (forward_inst) { if (inst->seqNum <= outReadSeqNum[tid]) { - int dest_reg_idx = forward_inst->getDestIdxNum(reg_idx); + int dest_reg_idx = + forward_inst->getDestIdxNum(reg_idx); if (reg_idx < FP_Base_DepTag) { - DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from " + DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest." + " reg value 0x%x from " "[sn:%i] to [sn:%i] source #%i.\n", - tid, forward_inst->readIntResult(dest_reg_idx) , - forward_inst->seqNum, inst->seqNum, ud_idx); - inst->setIntSrc(ud_idx, forward_inst->readIntResult(dest_reg_idx)); + tid, + forward_inst->readIntResult(dest_reg_idx), + forward_inst->seqNum, + inst->seqNum, ud_idx); + inst->setIntSrc(ud_idx, + forward_inst-> + readIntResult(dest_reg_idx)); } else if (reg_idx < Ctrl_Base_DepTag) { - DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from " + DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest." + " reg value 0x%x from " "[sn:%i] to [sn:%i] source #%i.\n", - tid, forward_inst->readFloatResult(dest_reg_idx) , + tid, + forward_inst->readFloatResult(dest_reg_idx), forward_inst->seqNum, inst->seqNum, ud_idx); inst->setFloatSrc(ud_idx, - forward_inst->readFloatResult(dest_reg_idx)); + forward_inst-> + readFloatResult(dest_reg_idx)); } else { - DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from " + DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest." + " reg value 0x%x from " "[sn:%i] to [sn:%i] source #%i.\n", - tid, forward_inst->readIntResult(dest_reg_idx) , - forward_inst->seqNum, inst->seqNum, ud_idx); - inst->setIntSrc(ud_idx, forward_inst->readIntResult(dest_reg_idx)); + tid, + forward_inst->readIntResult(dest_reg_idx), + forward_inst->seqNum, + inst->seqNum, ud_idx); + inst->setIntSrc(ud_idx, + forward_inst-> + readIntResult(dest_reg_idx)); } outReadSeqNum[tid] = maxSeqNum; ud_req->done(); } else { - DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because of [sn:%i] hasnt read it's" + DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read " + "because of [sn:%i] hasnt read it's" " registers yet.\n", tid, outReadSeqNum[tid]); - DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for [sn:%i] to forward\n", + DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for " + "[sn:%i] to forward\n", tid, outReadSeqNum[tid]); } } else { - DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i is not ready to read.\n", + DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i" + "is not ready to read.\n", tid, reg_idx); - DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to read register (idx=%i)\n", + DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to read " + "register (idx=%i)\n", tid, reg_idx); outReadSeqNum[tid] = inst->seqNum; } @@ -216,12 +268,14 @@ UseDefUnit::execute(int slot_idx) int reg_idx = inst->_destRegIdx[ud_idx]; if (regDepMap[tid]->canWrite(reg_idx, inst)) { - DPRINTF(InOrderUseDef, "[tid:%i]: Flattening register idx %i & Attempting to write to Register File.\n", + DPRINTF(InOrderUseDef, "[tid:%i]: Flattening register idx %i &" + "Attempting to write to Register File.\n", tid, reg_idx); - + uniqueRegMap[reg_idx] = true; if (inst->seqNum <= outReadSeqNum[tid]) { if (reg_idx < FP_Base_DepTag) { - DPRINTF(InOrderUseDef, "[tid:%i]: Writing Int. Result 0x%x to register idx %i.\n", + DPRINTF(InOrderUseDef, "[tid:%i]: Writing Int. Result " + "0x%x to register idx %i.\n", tid, inst->readIntResult(ud_idx), reg_idx); // Remove Dependencies @@ -236,33 +290,54 @@ UseDefUnit::execute(int slot_idx) reg_idx -= FP_Base_DepTag; - if (inst->resultType(ud_idx) == InOrderDynInst::Integer) { - DPRINTF(InOrderUseDef, "[tid:%i]: Writing FP-Bits Result 0x%x (bits:0x%x) to register idx %i.\n", - tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx); - - cpu->setFloatRegBits(reg_idx, // Check for FloatRegBits Here + if (inst->resultType(ud_idx) == + InOrderDynInst::Integer) { + DPRINTF(InOrderUseDef, "[tid:%i]: Writing FP-Bits " + "Result 0x%x (bits:0x%x) to register " + "idx %i.\n", + tid, + inst->readFloatResult(ud_idx), + inst->readIntResult(ud_idx), + reg_idx); + + // Check for FloatRegBits Here + cpu->setFloatRegBits(reg_idx, inst->readIntResult(ud_idx), inst->readTid()); - } else if (inst->resultType(ud_idx) == InOrderDynInst::Float) { - DPRINTF(InOrderUseDef, "[tid:%i]: Writing Float Result 0x%x (bits:0x%x) to register idx %i.\n", - tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx); + } else if (inst->resultType(ud_idx) == + InOrderDynInst::Float) { + DPRINTF(InOrderUseDef, "[tid:%i]: Writing Float " + "Result 0x%x (bits:0x%x) to register " + "idx %i.\n", + tid, inst->readFloatResult(ud_idx), + inst->readIntResult(ud_idx), + reg_idx); cpu->setFloatReg(reg_idx, inst->readFloatResult(ud_idx), inst->readTid()); - } else if (inst->resultType(ud_idx) == InOrderDynInst::Double) { - DPRINTF(InOrderUseDef, "[tid:%i]: Writing Double Result 0x%x (bits:0x%x) to register idx %i.\n", - tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx); - - cpu->setFloatReg(reg_idx, // Check for FloatRegBits Here + } else if (inst->resultType(ud_idx) == + InOrderDynInst::Double) { + DPRINTF(InOrderUseDef, "[tid:%i]: Writing Double " + "Result 0x%x (bits:0x%x) to register " + "idx %i.\n", + tid, + inst->readFloatResult(ud_idx), + inst->readIntResult(ud_idx), + reg_idx); + + // Check for FloatRegBits Here + cpu->setFloatReg(reg_idx, inst->readFloatResult(ud_idx), inst->readTid()); } else { - panic("Result Type Not Set For [sn:%i] %s.\n", inst->seqNum, inst->instName()); + panic("Result Type Not Set For [sn:%i] %s.\n", + inst->seqNum, inst->instName()); } } else { - DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x to register idx %i.\n", + DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x " + "to register idx %i.\n", tid, inst->readIntResult(ud_idx), reg_idx); // Remove Dependencies @@ -279,15 +354,19 @@ UseDefUnit::execute(int slot_idx) ud_req->done(); } else { - DPRINTF(InOrderUseDef, "[tid:%i]: Unable to write because of [sn:%i] hasnt read it's" + DPRINTF(InOrderUseDef, "[tid:%i]: Unable to write because " + "of [sn:%i] hasnt read it's" " registers yet.\n", tid, outReadSeqNum); - DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for [sn:%i] to read\n", + DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for " + "[sn:%i] to read\n", tid, outReadSeqNum); } } else { - DPRINTF(InOrderUseDef, "[tid:%i]: Dest. register idx: %i is not ready to write.\n", + DPRINTF(InOrderUseDef, "[tid:%i]: Dest. register idx: %i is " + "not ready to write.\n", tid, reg_idx); - DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write register (idx=%i)\n", + DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write " + "register (idx=%i)\n", tid, reg_idx); outWriteSeqNum[tid] = inst->seqNum; } @@ -343,18 +422,29 @@ UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, } if (outReadSeqNum[tid] >= squash_seq_num) { - DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Read Seq Num Reset.\n", tid); + DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Read Seq Num Reset.\n", + tid); outReadSeqNum[tid] = maxSeqNum; } else if (outReadSeqNum[tid] != maxSeqNum) { - DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Read Seq Num %i\n", + DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Read " + "Seq Num %i\n", tid, outReadSeqNum[tid]); } if (outWriteSeqNum[tid] >= squash_seq_num) { - DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Write Seq Num Reset.\n", tid); + DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Write Seq Num Reset.\n", + tid); outWriteSeqNum[tid] = maxSeqNum; } else if (outWriteSeqNum[tid] != maxSeqNum) { - DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Write Seq Num %i\n", + DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Write " + "Seq Num %i\n", tid, outWriteSeqNum[tid]); } } + +void +UseDefUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid) +{ + uniqueRegsPerSwitch = uniqueRegMap.size(); + uniqueRegMap.clear(); +} diff --git a/src/cpu/inorder/resources/use_def.hh b/src/cpu/inorder/resources/use_def.hh index 6c76d8ab5..41d758dd7 100644 --- a/src/cpu/inorder/resources/use_def.hh +++ b/src/cpu/inorder/resources/use_def.hh @@ -68,8 +68,12 @@ class UseDefUnit : public Resource { virtual void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, ThreadID tid); + void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid); + const InstSeqNum maxSeqNum; + void regStats(); + protected: RegDepMap *regDepMap[ThePipeline::MaxThreads]; @@ -84,14 +88,18 @@ class UseDefUnit : public Resource { InstSeqNum floatRegSize[ThePipeline::MaxThreads]; + Stats::Average uniqueRegsPerSwitch; + std::map uniqueRegMap; + public: class UseDefRequest : public ResourceRequest { public: typedef ThePipeline::DynInstPtr DynInstPtr; public: - UseDefRequest(UseDefUnit *res, DynInstPtr inst, int stage_num, int res_idx, - int slot_num, unsigned cmd, int use_def_idx) + UseDefRequest(UseDefUnit *res, DynInstPtr inst, int stage_num, + int res_idx, int slot_num, unsigned cmd, + int use_def_idx) : ResourceRequest(res, inst, stage_num, res_idx, slot_num, cmd), useDefIdx(use_def_idx) { } -- cgit v1.2.3