inorder: pipeline stage stats
authorKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:28:51 +0000 (18:28 -0500)
committerKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:28:51 +0000 (18:28 -0500)
add idle/run/utilization stats for each pipeline stage

src/cpu/inorder/cpu.cc
src/cpu/inorder/first_stage.cc
src/cpu/inorder/pipeline_stage.cc
src/cpu/inorder/pipeline_stage.hh

index d8fea79d9ae2b399ccf33d6a034638b836655bec..4cc9b9f22443b12e2f1d853580c69d57858846a4 100644 (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);
 }
index 27831469e0878d841b26912a795e2d5ac2e79e31..c653d152bbc4a3782fc57648a0f3f9db4df2ec8b 100644 (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
index 79f1ff915c3eac239789d94a13e516ea26372752..e601edfccfb109b6699fa2a856afa49cb90c59aa 100644 (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;
     }
 
index 920734e6a14bd23467592e18e0d9a66a97342d4d..be3a1093caa3ec838d6a43f1fd9ec3d1e6d13c51 100644 (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