changeset edf3d0c7a485 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=edf3d0c7a485
description:
        inorder: squash on memory stall
        add code to recognize memory stalls in resources and the pipeline as 
well
        as squash a thread if there is a stall and we are in the switch on 
cache miss
        model

diffstat:

12 files changed, 278 insertions(+), 106 deletions(-)
src/cpu/inorder/cpu.cc                  |   29 ++++
src/cpu/inorder/cpu.hh                  |    8 +
src/cpu/inorder/first_stage.cc          |   44 ++++---
src/cpu/inorder/first_stage.hh          |    2 
src/cpu/inorder/pipeline_stage.cc       |   35 ++++-
src/cpu/inorder/pipeline_stage.hh       |    2 
src/cpu/inorder/resource.cc             |    8 +
src/cpu/inorder/resource.hh             |   12 +-
src/cpu/inorder/resource_pool.cc        |  185 ++++++++++++++++++++-----------
src/cpu/inorder/resource_pool.hh        |    8 +
src/cpu/inorder/resources/cache_unit.cc |   48 ++++++--
src/cpu/inorder/resources/cache_unit.hh |    3 

diffs (truncated from 832 to 300 lines):

diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/cpu.cc    Sun Jan 31 18:26:13 2010 -0500
@@ -140,6 +140,10 @@
         cpu->disableThreads(tid, vpe);
         break;
 
+      case SquashFromMemStall:
+        cpu->squashDueToMemStall(inst->squashingStage, inst->seqNum, tid);
+        break;
+
       case Trap:
         cpu->trapCPU(fault, tid);
         break;
@@ -579,6 +583,31 @@
     fault->invoke(tcBase(tid));
 }
 
+void 
+InOrderCPU::squashFromMemStall(DynInstPtr inst, ThreadID tid, int delay)
+{
+    scheduleCpuEvent(SquashFromMemStall, NoFault, tid, inst, delay);
+}
+
+
+void
+InOrderCPU::squashDueToMemStall(int stage_num, InstSeqNum seq_num, ThreadID 
tid)
+{
+    DPRINTF(InOrderCPU, "Squashing Pipeline Stages Due to Memory Stall...\n");
+        
+    // Squash all instructions in each stage including 
+    // instruction that caused the squash (seq_num - 1)
+    // NOTE: The stage bandwidth needs to be cleared so thats why
+    //       the stalling instruction is squashed as well. The stalled
+    //       instruction is previously placed in another intermediate buffer
+    //       while it's stall is being handled.
+    InstSeqNum squash_seq_num = seq_num - 1;
+    
+    for (int stNum=stage_num; stNum >= 0 ; stNum--) {
+        pipelineStage[stNum]->squashDueToMemStall(squash_seq_num, tid);
+    }
+}
+
 void
 InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault,
                              ThreadID tid, DynInstPtr inst, 
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh    Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/cpu.hh    Sun Jan 31 18:26:13 2010 -0500
@@ -183,7 +183,7 @@
         EnableVPEs,
         Trap,
         InstGraduated,
-        SquashAll,
+        SquashFromMemStall,
         UpdatePCs,
         NumCPUEvents
     };
@@ -344,6 +344,12 @@
     void trap(Fault fault, ThreadID tid, int delay = 0);
     void trapCPU(Fault fault, ThreadID tid);
 
+    /** squashFromMemStall() - sets up a squash event
+     *  squashDueToMemStall() - squashes pipeline
+     */
+    void squashFromMemStall(DynInstPtr inst, ThreadID tid, int delay = 0);
+    void squashDueToMemStall(int stage_num, InstSeqNum seq_num, ThreadID tid); 
   
+
     /** Setup CPU to insert a thread's context */
     void insertThread(ThreadID tid);
 
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/first_stage.cc
--- a/src/cpu/inorder/first_stage.cc    Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/first_stage.cc    Sun Jan 31 18:26:13 2010 -0500
@@ -67,11 +67,12 @@
 
     // Clear the instruction list and skid buffer in case they have any
     // insts in them.
-    DPRINTF(InOrderStage, "Removing instructions from stage instruction 
list.\n");
+    DPRINTF(InOrderStage, "Removing instructions from stage instruction "
+            "list.\n");
     while (!insts[tid].empty()) {
         if (insts[tid].front()->seqNum <= squash_seq_num) {
-            DPRINTF(InOrderStage,"[tid:%i]: Cannot remove [sn:%i] because it's 
<= "
-                    "squashing seqNum %i.\n",
+            DPRINTF(InOrderStage,"[tid:%i]: Cannot remove [sn:%i] because "
+                    "it's <= squashing seqNum %i.\n",
                     tid,
                     insts[tid].front()->seqNum,
                     squash_seq_num);
@@ -82,8 +83,9 @@
                     insts[tid].size());
             break;
         }
-        DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] PC 
%08p.\n",
-                tid, insts[tid].front()->seqNum, insts[tid].front()->PC);
+        DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
+                "PC %08p.\n", tid, insts[tid].front()->seqNum, 
+                insts[tid].front()->PC);
         insts[tid].pop();
     }
 
@@ -93,6 +95,18 @@
     cpu->removeInstsUntil(squash_seq_num, tid);
 }
 
+void 
+FirstStage::squashDueToMemStall(InstSeqNum seq_num, ThreadID tid)
+{
+    // Need to preserve the stalling instruction in first-stage
+    // since the squash() from first stage also removes
+    // the instruction from the CPU (removeInstsUntil). If that
+    // functionality gets changed then you can move this offset.
+    // (stalling instruction = seq_num + 1)
+    squash(seq_num+1, tid);
+}
+
+
 void
 FirstStage::processStage(bool &status_change)
 {
@@ -106,6 +120,7 @@
 
     for (int threadFetched = 0; threadFetched < numFetchingThreads;
          threadFetched++) {
+
         ThreadID tid = getFetchingThread(fetchPolicy);
 
         if (tid >= 0) {
@@ -117,14 +132,17 @@
     }
 }
 
-//@TODO: Note in documentation, that when you make a pipeline stage change, 
then
-//make sure you change the first stage too
+//@TODO: Note in documentation, that when you make a pipeline stage change, 
+//then make sure you change the first stage too
 void
 FirstStage::processInsts(ThreadID tid)
 {
     bool all_reqs_completed = true;
 
-    for (int insts_fetched = 0; insts_fetched < stageWidth && 
canSendInstToStage(1); insts_fetched++) {
+    for (int insts_fetched = 0; 
+         insts_fetched < stageWidth && canSendInstToStage(1); 
+         insts_fetched++) {
+
         DynInstPtr inst;
         bool new_inst = false;
 
@@ -150,19 +168,9 @@
             inst->traceData = NULL;
 #endif      // TRACING_ON
 
-            DPRINTF(RefCount, "creation: [tid:%i]: [sn:%i]: Refcount = %i.\n",
-                    inst->readTid(),
-                    inst->seqNum,
-                    0/*inst->curCount()*/);
-
             // Add instruction to the CPU's list of instructions.
             inst->setInstListIt(cpu->addInst(inst));
 
-            DPRINTF(RefCount, "after add to CPU List: [tid:%i]: [sn:%i]: 
Refcount = %i.\n",
-                    inst->readTid(),
-                    inst->seqNum,
-                    0/*inst->curCount()*/);
-
             // Create Front-End Resource Schedule For Instruction
             ThePipeline::createFrontEndSchedule(inst);
         }
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/first_stage.hh
--- a/src/cpu/inorder/first_stage.hh    Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/first_stage.hh    Sun Jan 31 18:26:13 2010 -0500
@@ -61,6 +61,8 @@
     /** Squash Instructions Above a Seq. Num */
     void squash(InstSeqNum squash_seq_num, ThreadID tid);
 
+    void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
+
     /** There are no insts. coming from previous stages, so there is
      * no need to sort insts here
      */
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:26:13 2010 -0500
@@ -339,9 +339,9 @@
 {
     if (cpu->squashSeqNum[tid] < inst->seqNum &&
         cpu->lastSquashCycle[tid] == curTick){
-        DPRINTF(Resource, "Ignoring [sn:%i] squash signal due to another "
-                "stage's squash signal for after [sn:%i].\n", inst->seqNum, 
-                cpu->squashSeqNum[tid]);
+        DPRINTF(Resource, "Ignoring [sn:%i] branch squash signal due to "
+                "another stage's squash signal for after [sn:%i].\n", 
+                inst->seqNum, cpu->squashSeqNum[tid]);
     } else {
         // Send back mispredict information.
         toPrevStages->stageInfo[stageNum][tid].branchMispredict = true;
@@ -382,6 +382,12 @@
 }
 
 void
+PipelineStage::squashDueToMemStall(InstSeqNum seq_num, ThreadID tid)
+{
+    squash(seq_num, tid);    
+}
+
+void
 PipelineStage::squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid)
 {
     DPRINTF(InOrderStage, "[tid:%i]: Removing instructions from "
@@ -413,8 +419,9 @@
     while (!skidBuffer[tid].empty()) {
         if (skidBuffer[tid].front()->seqNum <= squash_seq_num) {
             DPRINTF(InOrderStage, "[tid:%i]: Cannot remove skidBuffer "
-                    "instructions before delay slot [sn:%i]. %i insts"
-                    "left.\n", tid, squash_seq_num,
+                    "instructions (starting w/[sn:%i]) before delay slot "
+                    "[sn:%i]. %i insts left.\n", tid, 
+                    skidBuffer[tid].front()->seqNum, squash_seq_num,
                     skidBuffer[tid].size());
             break;
         }
@@ -775,7 +782,7 @@
 PipelineStage::processThread(bool &status_change, ThreadID tid)
 {
     // If status is Running or idle,
-    //     call stageInsts()
+    //     call processInsts()
     // If status is Unblocking,
     //     buffer any instructions coming from fetch
     //     continue trying to empty skid buffer
@@ -787,7 +794,7 @@
         ;//++stageSquashCycles;
     }
 
-    // Stage should try to stage 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.
     if (stageStatus[tid] == Running ||
         stageStatus[tid] == Idle) {
@@ -904,9 +911,7 @@
 PipelineStage::processInstSchedule(DynInstPtr inst)
 {
     bool last_req_completed = true;
-#if TRACING_ON
     ThreadID tid = inst->readTid();
-#endif
 
     if (inst->nextResStage() == stageNum) {
         int res_stage_num = inst->nextResStage();
@@ -937,6 +942,18 @@
 
                 last_req_completed = false;
 
+                if (req->isMemStall() && 
+                    cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
+                    // Save Stalling Instruction
+                    switchedOutBuffer[tid] = inst;
+                    switchedOutValid[tid] = true;
+                    
+                    // Remove Thread From Pipeline & Resource Pool
+                    inst->squashingStage = stageNum;         
+                    inst->bdelaySeqNum = inst->seqNum;                         
      
+                    cpu->squashFromMemStall(inst, tid);                    
+                }
+                
                 break;
             }
 
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/pipeline_stage.hh
--- a/src/cpu/inorder/pipeline_stage.hh Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/pipeline_stage.hh Sun Jan 31 18:26:13 2010 -0500
@@ -240,7 +240,7 @@
      */
     virtual void squashDueToBranch(DynInstPtr &inst, ThreadID tid);
 
-    virtual void squashDueToMemStall(DynInstPtr &inst, ThreadID tid);
+    virtual void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
 
     /** Squash instructions from stage buffer  */
     virtual void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/resource.cc
--- a/src/cpu/inorder/resource.cc       Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/resource.cc       Sun Jan 31 18:26:13 2010 -0500
@@ -340,6 +340,12 @@
     }
 }
 
+void
+Resource::squashDueToMemStall(DynInstPtr inst, int stage_num, InstSeqNum 
squash_seq_num,
+                              ThreadID tid)
+{
+    squash(inst, stage_num, squash_seq_num, tid);    
+}
 
 Tick
 Resource::ticks(int num_cycles)
@@ -407,7 +413,7 @@
                                  unsigned _cmd)
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to