inorder: pipeline stage stats

add idle/run/utilization stats for each pipeline stage
This commit is contained in:
Korey Sewell 2010-01-31 18:28:51 -05:00
parent 4d749472e3
commit ffa9ecb1fa
4 changed files with 55 additions and 62 deletions

View file

@ -346,6 +346,11 @@ InOrderCPU::regStats()
.prereq(maxResReqCount);
#endif
/* Register for each Pipeline Stage */
for (int stage_num=0; stage_num < ThePipeline::NumStages; stage_num++) {
pipelineStage[stage_num]->regStats();
}
/* Register any of the InOrderCPU's stats here.*/
timesIdled
.name(name() + ".timesIdled")
@ -1289,8 +1294,14 @@ InOrderCPU::wakeCPU()
DPRINTF(Activity, "Waking up CPU\n");
//@todo: figure out how to count idleCycles correctly
//idleCycles += (curTick - 1) - lastRunningCycle;
Tick extra_cycles = tickToCycles((curTick - 1) - lastRunningCycle);
idleCycles += extra_cycles;
for (int stage_num = 0; stage_num < NumStages; stage_num++) {
pipelineStage[stage_num]->idleCycles += extra_cycles;
}
numCycles += extra_cycles;
mainEventQueue.schedule(&tickEvent, curTick);
}

View file

@ -118,9 +118,9 @@ FirstStage::processStage(bool &status_change)
status_change = checkSignalsAndUpdate(tid) || status_change;
}
for (int threadFetched = 0; threadFetched < numFetchingThreads;
threadFetched++) {
for (int insts_fetched = 0;
insts_fetched < stageWidth && canSendInstToStage(1);
insts_fetched++) {
ThreadID tid = getFetchingThread(fetchPolicy);
if (tid >= 0) {
@ -130,6 +130,13 @@ FirstStage::processStage(bool &status_change)
DPRINTF(InOrderStage, "No more threads to fetch from.\n");
}
}
if (instsProcessed > 0) {
++runCycles;
} else {
++idleCycles;
}
}
//@TODO: Note in documentation, that when you make a pipeline stage change,
@ -197,7 +204,6 @@ FirstStage::processInsts(ThreadID tid)
}
sendInstToNextStage(inst);
//++stageProcessedInsts;
}
// Record that stage has written to the time buffer for activity

View file

@ -72,41 +72,27 @@ PipelineStage::init(Params *params)
std::string
PipelineStage::name() const
{
return cpu->name() + ".stage-" + to_string(stageNum);
return cpu->name() + ".stage-" + to_string(stageNum);
}
void
PipelineStage::regStats()
{
/* stageIdleCycles
.name(name() + ".IdleCycles")
.desc("Number of cycles stage is idle")
.prereq(stageIdleCycles);
stageBlockedCycles
.name(name() + ".BlockedCycles")
.desc("Number of cycles stage is blocked")
.prereq(stageBlockedCycles);
stageRunCycles
.name(name() + ".RunCycles")
.desc("Number of cycles stage is running")
.prereq(stageRunCycles);
stageUnblockCycles
.name(name() + ".UnblockCycles")
.desc("Number of cycles stage is unblocking")
.prereq(stageUnblockCycles);
stageSquashCycles
.name(name() + ".SquashCycles")
.desc("Number of cycles stage is squashing")
.prereq(stageSquashCycles);
stageProcessedInsts
.name(name() + ".ProcessedInsts")
.desc("Number of instructions handled by stage")
.prereq(stageProcessedInsts);
stageSquashedInsts
.name(name() + ".SquashedInsts")
.desc("Number of squashed instructions handled by stage")
.prereq(stageSquashedInsts);*/
idleCycles
.name(name() + ".idleCycles")
.desc("Number of cycles 0 instructions are processed.");
runCycles
.name(name() + ".runCycles")
.desc("Number of cycles 1+ instructions are processed.");
utilization
.name(name() + ".utilization")
.desc("Percentage of cycles stage was utilized (processing insts).")
.precision(6);
utilization = (runCycles / cpu->numCycles) * 100;
}
@ -803,6 +789,12 @@ PipelineStage::processStage(bool &status_change)
nextStage->size, stageNum + 1);
}
if (instsProcessed > 0) {
++runCycles;
} else {
++idleCycles;
}
DPRINTF(InOrderStage, "%i left in stage %i incoming buffer.\n", skidSize(),
stageNum);
@ -820,12 +812,6 @@ PipelineStage::processThread(bool &status_change, ThreadID tid)
// continue trying to empty skid buffer
// check if stall conditions have passed
if (stageStatus[tid] == Blocked) {
;//++stageBlockedCycles;
} else if (stageStatus[tid] == Squashing) {
;//++stageSquashCycles;
}
// Stage should try to process as many instructions as its bandwidth
// will allow, as long as it is not currently blocked.
if (stageStatus[tid] == Running ||
@ -867,8 +853,6 @@ PipelineStage::processInsts(ThreadID tid)
if (insts_available == 0) {
DPRINTF(InOrderStage, "[tid:%u]: Nothing to do, breaking out"
" early.\n",tid);
// Should I change the status to idle?
//++stageIdleCycles;
return;
}
@ -892,8 +876,6 @@ PipelineStage::processInsts(ThreadID tid)
"squashed, skipping.\n",
tid, inst->seqNum, inst->readPC());
//++stageSquashedInsts;
insts_to_stage.pop();
--insts_available;
@ -924,7 +906,6 @@ PipelineStage::processInsts(ThreadID tid)
insts_to_stage.pop();
//++stageProcessedInsts;
--insts_available;
}

View file

@ -353,24 +353,19 @@ class PipelineStage
std::vector<ResReqPtr> resources;
};
/** Tracks which stages are telling decode to stall. */
/** Tracks stage/resource stalls */
Stalls stalls[ThePipeline::MaxThreads];
//@TODO: Use Stats for the pipeline stages
/** Stat for total number of idle cycles. */
//Stats::Scalar stageIdleCycles;
/** Stat for total number of blocked cycles. */
//Stats::Scalar stageBlockedCycles;
/** Stat for total number of normal running cycles. */
//Stats::Scalar stageRunCycles;
/** Stat for total number of unblocking cycles. */
//Stats::Scalar stageUnblockCycles;
/** Stat for total number of squashing cycles. */
//Stats::Scalar stageSquashCycles;
/** Stat for total number of staged instructions. */
//Stats::Scalar stageProcessedInsts;
/** Stat for total number of squashed instructions. */
//Stats::Scalar stageSquashedInsts;
/** Number of cycles 0 instruction(s) are processed. */
Stats::Scalar idleCycles;
/** Number of cycles 1+ instructions are processed. */
Stats::Scalar runCycles;
/** Percentage of cycles 1+ instructions are processed. */
Stats::Formula utilization;
};
#endif