inorder: ctxt switch stats
- m5 line enforcement on use_def.cc,hh
This commit is contained in:
parent
ffa9ecb1fa
commit
0b29c2d057
6 changed files with 194 additions and 66 deletions
|
@ -189,7 +189,8 @@ InOrderCPU::InOrderCPU(Params *params)
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
switchCount(0),
|
switchCount(0),
|
||||||
deferRegistration(false/*params->deferRegistration*/),
|
deferRegistration(false/*params->deferRegistration*/),
|
||||||
stageTracing(params->stageTracing)
|
stageTracing(params->stageTracing),
|
||||||
|
instsPerSwitch(0)
|
||||||
{
|
{
|
||||||
ThreadID active_threads;
|
ThreadID active_threads;
|
||||||
cpu_params = params;
|
cpu_params = params;
|
||||||
|
@ -352,6 +353,15 @@ InOrderCPU::regStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register any of the InOrderCPU's stats here.*/
|
/* 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
|
timesIdled
|
||||||
.name(name() + ".timesIdled")
|
.name(name() + ".timesIdled")
|
||||||
.desc("Number of times that the entire CPU went into an idle state and"
|
.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);
|
tcBase(tid)->setStatus(ThreadContext::Active);
|
||||||
|
|
||||||
wakeCPU();
|
wakeCPU();
|
||||||
|
|
||||||
|
numCtxtSwitches++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1056,6 +1068,15 @@ InOrderCPU::addInst(DynInstPtr &inst)
|
||||||
return --(instList[tid].end());
|
return --(instList[tid].end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderCPU::updateContextSwitchStats()
|
||||||
|
{
|
||||||
|
// Set Average Stat Here, then reset to 0
|
||||||
|
instsPerCtxtSwitch = instsPerSwitch;
|
||||||
|
instsPerSwitch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
|
InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
|
||||||
{
|
{
|
||||||
|
@ -1086,6 +1107,9 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
|
||||||
inst->traceData = NULL;
|
inst->traceData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment active thread's instruction count
|
||||||
|
instsPerSwitch++;
|
||||||
|
|
||||||
// Increment thread-state's instruction count
|
// Increment thread-state's instruction count
|
||||||
thread[tid]->numInst++;
|
thread[tid]->numInst++;
|
||||||
|
|
||||||
|
|
|
@ -707,6 +707,11 @@ class InOrderCPU : public BaseCPU
|
||||||
/** The cycle that the CPU was last running, used for statistics. */
|
/** The cycle that the CPU was last running, used for statistics. */
|
||||||
Tick lastRunningCycle;
|
Tick lastRunningCycle;
|
||||||
|
|
||||||
|
void updateContextSwitchStats();
|
||||||
|
unsigned instsPerSwitch;
|
||||||
|
Stats::Average instsPerCtxtSwitch;
|
||||||
|
Stats::Scalar numCtxtSwitches;
|
||||||
|
|
||||||
/** Update Thread , used for statistic purposes*/
|
/** Update Thread , used for statistic purposes*/
|
||||||
inline void tickThreadStats();
|
inline void tickThreadStats();
|
||||||
|
|
||||||
|
|
|
@ -570,6 +570,9 @@ PipelineStage::activateThread(ThreadID tid)
|
||||||
// Clear switchout buffer
|
// Clear switchout buffer
|
||||||
switchedOutBuffer[tid] = NULL;
|
switchedOutBuffer[tid] = NULL;
|
||||||
switchedOutValid[tid] = false;
|
switchedOutValid[tid] = false;
|
||||||
|
|
||||||
|
// Update any CPU stats based off context switches
|
||||||
|
cpu->updateContextSwitchStats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,6 @@ class GraduationUnit : public Resource {
|
||||||
bool *nonSpecInstActive[ThePipeline::MaxThreads];
|
bool *nonSpecInstActive[ThePipeline::MaxThreads];
|
||||||
|
|
||||||
InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
|
InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
|
||||||
|
|
||||||
/** @todo: Add Resource Stats Here */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__CPU_INORDER_GRAD_UNIT_HH__
|
#endif //__CPU_INORDER_GRAD_UNIT_HH__
|
||||||
|
|
|
@ -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
|
ResReqPtr
|
||||||
UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
|
UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
|
||||||
int slot_num, unsigned cmd)
|
int slot_num, unsigned cmd)
|
||||||
|
@ -75,7 +86,8 @@ UseDefUnit::findRequest(DynInstPtr inst)
|
||||||
map<int, ResReqPtr>::iterator map_end = reqMap.end();
|
map<int, ResReqPtr>::iterator map_end = reqMap.end();
|
||||||
|
|
||||||
while (map_it != map_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);
|
assert(ud_req);
|
||||||
|
|
||||||
if (ud_req &&
|
if (ud_req &&
|
||||||
|
@ -107,9 +119,9 @@ UseDefUnit::execute(int slot_idx)
|
||||||
// in the pipeline then stall instructions here
|
// in the pipeline then stall instructions here
|
||||||
if (*nonSpecInstActive[tid] == true &&
|
if (*nonSpecInstActive[tid] == true &&
|
||||||
seq_num > *nonSpecSeqNum[tid]) {
|
seq_num > *nonSpecSeqNum[tid]) {
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because there is "
|
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
|
||||||
"non-speculative instruction [sn:%i] has not graduated.\n",
|
"there is non-speculative instruction [sn:%i] has not "
|
||||||
tid, seq_num, *nonSpecSeqNum[tid]);
|
"graduated.\n", tid, seq_num, *nonSpecSeqNum[tid]);
|
||||||
return;
|
return;
|
||||||
} else if (inst->isNonSpeculative()) {
|
} else if (inst->isNonSpeculative()) {
|
||||||
*nonSpecInstActive[tid] = true;
|
*nonSpecInstActive[tid] = true;
|
||||||
|
@ -122,88 +134,128 @@ UseDefUnit::execute(int slot_idx)
|
||||||
{
|
{
|
||||||
int reg_idx = inst->_srcRegIdx[ud_idx];
|
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);
|
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)) {
|
if (regDepMap[tid]->canRead(reg_idx, inst)) {
|
||||||
|
|
||||||
|
uniqueRegMap[reg_idx] = true;
|
||||||
|
|
||||||
if (inst->seqNum <= outReadSeqNum[tid]) {
|
if (inst->seqNum <= outReadSeqNum[tid]) {
|
||||||
if (reg_idx < FP_Base_DepTag) {
|
if (reg_idx < FP_Base_DepTag) {
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Reading Int Reg %i from Register File:%i.\n",
|
DPRINTF(InOrderUseDef, "[tid:%i]: Reading Int Reg %i"
|
||||||
tid, reg_idx, cpu->readIntReg(reg_idx,inst->readTid()));
|
"from Register File:%i.\n",
|
||||||
inst->setIntSrc(ud_idx,
|
|
||||||
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",
|
|
||||||
tid,
|
tid,
|
||||||
reg_idx,
|
reg_idx,
|
||||||
cpu->readFloatRegBits(reg_idx, inst->readTid()),
|
cpu->readIntReg(reg_idx,inst->readTid()));
|
||||||
cpu->readFloatReg(reg_idx, inst->readTid()));
|
inst->setIntSrc(ud_idx,
|
||||||
|
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",
|
||||||
|
tid,
|
||||||
|
reg_idx,
|
||||||
|
cpu->readFloatRegBits(reg_idx,
|
||||||
|
inst->readTid()),
|
||||||
|
cpu->readFloatReg(reg_idx,
|
||||||
|
inst->readTid()));
|
||||||
|
|
||||||
inst->setFloatSrc(ud_idx,
|
inst->setFloatSrc(ud_idx,
|
||||||
cpu->readFloatReg(reg_idx, inst->readTid()));
|
cpu->readFloatReg(reg_idx,
|
||||||
|
inst->readTid()));
|
||||||
} else {
|
} else {
|
||||||
reg_idx -= Ctrl_Base_DepTag;
|
reg_idx -= Ctrl_Base_DepTag;
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Reading Misc Reg %i from Register File:%i.\n",
|
DPRINTF(InOrderUseDef, "[tid:%i]: Reading Misc Reg %i "
|
||||||
tid, reg_idx, cpu->readMiscReg(reg_idx, inst->readTid()));
|
"from Register File:%i.\n",
|
||||||
|
tid,
|
||||||
|
reg_idx,
|
||||||
|
cpu->readMiscReg(reg_idx,
|
||||||
|
inst->readTid()));
|
||||||
inst->setIntSrc(ud_idx,
|
inst->setIntSrc(ud_idx,
|
||||||
cpu->readMiscReg(reg_idx, inst->readTid()));
|
cpu->readMiscReg(reg_idx,
|
||||||
|
inst->readTid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
outReadSeqNum[tid] = maxSeqNum;
|
outReadSeqNum[tid] = maxSeqNum;
|
||||||
|
|
||||||
ud_req->done();
|
ud_req->done();
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because of [sn:%i] hasnt read it's"
|
DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because "
|
||||||
" registers yet.\n", tid, outReadSeqNum[tid]);
|
"of [sn:%i] hasnt read it's registers yet.\n",
|
||||||
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for [sn:%i] to write\n",
|
tid, outReadSeqNum[tid]);
|
||||||
|
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
|
||||||
|
"[sn:%i] to write\n",
|
||||||
tid, outReadSeqNum[tid]);
|
tid, outReadSeqNum[tid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Look for forwarding opportunities
|
// 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 (forward_inst) {
|
||||||
|
|
||||||
if (inst->seqNum <= outReadSeqNum[tid]) {
|
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) {
|
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",
|
"[sn:%i] to [sn:%i] source #%i.\n",
|
||||||
tid, forward_inst->readIntResult(dest_reg_idx) ,
|
tid,
|
||||||
forward_inst->seqNum, inst->seqNum, ud_idx);
|
forward_inst->readIntResult(dest_reg_idx),
|
||||||
inst->setIntSrc(ud_idx, 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) {
|
} 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",
|
"[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);
|
forward_inst->seqNum, inst->seqNum, ud_idx);
|
||||||
inst->setFloatSrc(ud_idx,
|
inst->setFloatSrc(ud_idx,
|
||||||
forward_inst->readFloatResult(dest_reg_idx));
|
forward_inst->
|
||||||
|
readFloatResult(dest_reg_idx));
|
||||||
} else {
|
} 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",
|
"[sn:%i] to [sn:%i] source #%i.\n",
|
||||||
tid, forward_inst->readIntResult(dest_reg_idx) ,
|
tid,
|
||||||
forward_inst->seqNum, inst->seqNum, ud_idx);
|
forward_inst->readIntResult(dest_reg_idx),
|
||||||
inst->setIntSrc(ud_idx, 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;
|
outReadSeqNum[tid] = maxSeqNum;
|
||||||
|
|
||||||
ud_req->done();
|
ud_req->done();
|
||||||
} else {
|
} 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]);
|
" 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]);
|
tid, outReadSeqNum[tid]);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
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);
|
tid, reg_idx);
|
||||||
outReadSeqNum[tid] = inst->seqNum;
|
outReadSeqNum[tid] = inst->seqNum;
|
||||||
}
|
}
|
||||||
|
@ -216,12 +268,14 @@ UseDefUnit::execute(int slot_idx)
|
||||||
int reg_idx = inst->_destRegIdx[ud_idx];
|
int reg_idx = inst->_destRegIdx[ud_idx];
|
||||||
|
|
||||||
if (regDepMap[tid]->canWrite(reg_idx, inst)) {
|
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);
|
tid, reg_idx);
|
||||||
|
uniqueRegMap[reg_idx] = true;
|
||||||
if (inst->seqNum <= outReadSeqNum[tid]) {
|
if (inst->seqNum <= outReadSeqNum[tid]) {
|
||||||
if (reg_idx < FP_Base_DepTag) {
|
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);
|
tid, inst->readIntResult(ud_idx), reg_idx);
|
||||||
|
|
||||||
// Remove Dependencies
|
// Remove Dependencies
|
||||||
|
@ -236,33 +290,54 @@ UseDefUnit::execute(int slot_idx)
|
||||||
|
|
||||||
reg_idx -= FP_Base_DepTag;
|
reg_idx -= FP_Base_DepTag;
|
||||||
|
|
||||||
if (inst->resultType(ud_idx) == InOrderDynInst::Integer) {
|
if (inst->resultType(ud_idx) ==
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Writing FP-Bits Result 0x%x (bits:0x%x) to register idx %i.\n",
|
InOrderDynInst::Integer) {
|
||||||
tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
|
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
|
// Check for FloatRegBits Here
|
||||||
|
cpu->setFloatRegBits(reg_idx,
|
||||||
inst->readIntResult(ud_idx),
|
inst->readIntResult(ud_idx),
|
||||||
inst->readTid());
|
inst->readTid());
|
||||||
} else if (inst->resultType(ud_idx) == InOrderDynInst::Float) {
|
} else if (inst->resultType(ud_idx) ==
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Writing Float Result 0x%x (bits:0x%x) to register idx %i.\n",
|
InOrderDynInst::Float) {
|
||||||
tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
|
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,
|
cpu->setFloatReg(reg_idx,
|
||||||
inst->readFloatResult(ud_idx),
|
inst->readFloatResult(ud_idx),
|
||||||
inst->readTid());
|
inst->readTid());
|
||||||
} else if (inst->resultType(ud_idx) == InOrderDynInst::Double) {
|
} else if (inst->resultType(ud_idx) ==
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Writing Double Result 0x%x (bits:0x%x) to register idx %i.\n",
|
InOrderDynInst::Double) {
|
||||||
tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
|
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
|
// Check for FloatRegBits Here
|
||||||
|
cpu->setFloatReg(reg_idx,
|
||||||
inst->readFloatResult(ud_idx),
|
inst->readFloatResult(ud_idx),
|
||||||
inst->readTid());
|
inst->readTid());
|
||||||
} else {
|
} 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 {
|
} 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);
|
tid, inst->readIntResult(ud_idx), reg_idx);
|
||||||
|
|
||||||
// Remove Dependencies
|
// Remove Dependencies
|
||||||
|
@ -279,15 +354,19 @@ UseDefUnit::execute(int slot_idx)
|
||||||
|
|
||||||
ud_req->done();
|
ud_req->done();
|
||||||
} else {
|
} 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);
|
" 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);
|
tid, outReadSeqNum);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
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);
|
tid, reg_idx);
|
||||||
outWriteSeqNum[tid] = inst->seqNum;
|
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) {
|
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;
|
outReadSeqNum[tid] = maxSeqNum;
|
||||||
} else if (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]);
|
tid, outReadSeqNum[tid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outWriteSeqNum[tid] >= squash_seq_num) {
|
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;
|
outWriteSeqNum[tid] = maxSeqNum;
|
||||||
} else if (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]);
|
tid, outWriteSeqNum[tid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UseDefUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
|
||||||
|
{
|
||||||
|
uniqueRegsPerSwitch = uniqueRegMap.size();
|
||||||
|
uniqueRegMap.clear();
|
||||||
|
}
|
||||||
|
|
|
@ -68,8 +68,12 @@ class UseDefUnit : public Resource {
|
||||||
virtual void squash(DynInstPtr inst, int stage_num,
|
virtual void squash(DynInstPtr inst, int stage_num,
|
||||||
InstSeqNum squash_seq_num, ThreadID tid);
|
InstSeqNum squash_seq_num, ThreadID tid);
|
||||||
|
|
||||||
|
void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid);
|
||||||
|
|
||||||
const InstSeqNum maxSeqNum;
|
const InstSeqNum maxSeqNum;
|
||||||
|
|
||||||
|
void regStats();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RegDepMap *regDepMap[ThePipeline::MaxThreads];
|
RegDepMap *regDepMap[ThePipeline::MaxThreads];
|
||||||
|
|
||||||
|
@ -84,14 +88,18 @@ class UseDefUnit : public Resource {
|
||||||
|
|
||||||
InstSeqNum floatRegSize[ThePipeline::MaxThreads];
|
InstSeqNum floatRegSize[ThePipeline::MaxThreads];
|
||||||
|
|
||||||
|
Stats::Average uniqueRegsPerSwitch;
|
||||||
|
std::map<unsigned, bool> uniqueRegMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class UseDefRequest : public ResourceRequest {
|
class UseDefRequest : public ResourceRequest {
|
||||||
public:
|
public:
|
||||||
typedef ThePipeline::DynInstPtr DynInstPtr;
|
typedef ThePipeline::DynInstPtr DynInstPtr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UseDefRequest(UseDefUnit *res, DynInstPtr inst, int stage_num, int res_idx,
|
UseDefRequest(UseDefUnit *res, DynInstPtr inst, int stage_num,
|
||||||
int slot_num, unsigned cmd, int use_def_idx)
|
int res_idx, int slot_num, unsigned cmd,
|
||||||
|
int use_def_idx)
|
||||||
: ResourceRequest(res, inst, stage_num, res_idx, slot_num, cmd),
|
: ResourceRequest(res, inst, stage_num, res_idx, slot_num, cmd),
|
||||||
useDefIdx(use_def_idx)
|
useDefIdx(use_def_idx)
|
||||||
{ }
|
{ }
|
||||||
|
|
Loading…
Reference in a new issue