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); .prereq(maxResReqCount);
#endif #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.*/ /* Register any of the InOrderCPU's stats here.*/
timesIdled timesIdled
.name(name() + ".timesIdled") .name(name() + ".timesIdled")
@ -1289,8 +1294,14 @@ InOrderCPU::wakeCPU()
DPRINTF(Activity, "Waking up CPU\n"); DPRINTF(Activity, "Waking up CPU\n");
//@todo: figure out how to count idleCycles correctly Tick extra_cycles = tickToCycles((curTick - 1) - lastRunningCycle);
//idleCycles += (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); mainEventQueue.schedule(&tickEvent, curTick);
} }

View file

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

View file

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

View file

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