From ffa9ecb1fa71f1fe89a65975b2c558e312bbfbc8 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:28:51 -0500 Subject: inorder: pipeline stage stats add idle/run/utilization stats for each pipeline stage --- src/cpu/inorder/cpu.cc | 15 ++++++++-- src/cpu/inorder/first_stage.cc | 14 ++++++--- src/cpu/inorder/pipeline_stage.cc | 61 ++++++++++++++------------------------- src/cpu/inorder/pipeline_stage.hh | 27 +++++++---------- 4 files changed, 55 insertions(+), 62 deletions(-) (limited to 'src/cpu/inorder') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index d8fea79d9..4cc9b9f22 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -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); } diff --git a/src/cpu/inorder/first_stage.cc b/src/cpu/inorder/first_stage.cc index 27831469e..c653d152b 100644 --- a/src/cpu/inorder/first_stage.cc +++ b/src/cpu/inorder/first_stage.cc @@ -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 diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 79f1ff915..e601edfcc 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -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; } diff --git a/src/cpu/inorder/pipeline_stage.hh b/src/cpu/inorder/pipeline_stage.hh index 920734e6a..be3a1093c 100644 --- a/src/cpu/inorder/pipeline_stage.hh +++ b/src/cpu/inorder/pipeline_stage.hh @@ -353,24 +353,19 @@ class PipelineStage std::vector 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 -- cgit v1.2.3