summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2010-01-31 18:28:59 -0500
committerKorey Sewell <ksewell@umich.edu>2010-01-31 18:28:59 -0500
commit0b29c2d057d2d6f4f8b9b7853da91bcb283e805c (patch)
treee594abc10fc92baaed872fe7139153bd5a86ffcf
parentffa9ecb1fa71f1fe89a65975b2c558e312bbfbc8 (diff)
downloadgem5-0b29c2d057d2d6f4f8b9b7853da91bcb283e805c.tar.xz
inorder: ctxt switch stats
- m5 line enforcement on use_def.cc,hh
-rw-r--r--src/cpu/inorder/cpu.cc26
-rw-r--r--src/cpu/inorder/cpu.hh5
-rw-r--r--src/cpu/inorder/pipeline_stage.cc3
-rw-r--r--src/cpu/inorder/resources/graduation_unit.hh2
-rw-r--r--src/cpu/inorder/resources/use_def.cc216
-rw-r--r--src/cpu/inorder/resources/use_def.hh12
6 files changed, 196 insertions, 68 deletions
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<int, ResReqPtr>::iterator map_end = reqMap.end();
while (map_it != map_end) {
- UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>((*map_it).second);
+ UseDefRequest* ud_req =
+ dynamic_cast<UseDefRequest*>((*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<unsigned, bool> 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)
{ }