changeset 099ca6d9fc03 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=099ca6d9fc03
description:
        inorder: activate thread on cache miss
        -Support ability to activate next ready thread after a cache miss
        through the activateNextReadyContext/Thread() functions
        -To support this a "readyList" of thread ids is added
        -After a cache miss, thread will suspend and then call
        activitynextreadythread

diffstat:

5 files changed, 128 insertions(+), 23 deletions(-)
src/cpu/inorder/cpu.cc            |   78 ++++++++++++++++++++++++++++++++++---
src/cpu/inorder/cpu.hh            |   23 ++++++++++
src/cpu/inorder/pipeline_stage.cc |   10 ++++
src/cpu/inorder/resource_pool.cc  |   34 ++++++++++------
src/cpu/inorder/thread_context.cc |    6 +-

diffs (truncated from 315 to 300 lines):

diff -r d807273f17c0 -r 099ca6d9fc03 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Sun Jan 31 18:26:26 2010 -0500
+++ b/src/cpu/inorder/cpu.cc    Sun Jan 31 18:26:32 2010 -0500
@@ -96,6 +96,8 @@
 std::string InOrderCPU::eventNames[NumCPUEvents] =
 {
     "ActivateThread",
+    "ActivateNextReadyThread",
+    "DeactivateThread",
     "DeallocateThread",
     "SuspendThread",
     "DisableThreads",
@@ -119,9 +121,18 @@
 
       //@TODO: Consider Implementing "Suspend Thread" as Separate from 
       //Deallocate
+      case ActivateNextReadyThread:
+        cpu->activateNextReadyThread();
+        break;
+
+      case DeactivateThread:
+        cpu->deactivateThread(tid);
+        break;
+
       case SuspendThread: // Suspend & Deallocate are same for now.
-        //cpu->suspendThread(tid);
-        //break;
+        cpu->suspendThread(tid);
+        break;
+
       case DeallocateThread:
         cpu->deallocateThread(tid);
         break;
@@ -225,6 +236,14 @@
 
     if (active_threads > 1) {
         threadModel = (InOrderCPU::ThreadModel) params->threadModel;
+
+        if (threadModel == SMT) {
+            DPRINTF(InOrderCPU, "Setting Thread Model to SMT.\n");            
+        } else if (threadModel == SwitchOnCacheMiss) {
+            DPRINTF(InOrderCPU, "Setting Thread Model to "
+                    "Switch On Cache Miss\n");
+        }
+        
     } else {
         threadModel = Single;
     }
@@ -628,8 +647,8 @@
     }
 
     // Broadcast event to the Resource Pool
-    DynInstPtr dummy_inst =
-        new InOrderDynInst(this, NULL, getNextEventNum(), tid);
+    // Need to reset tid just in case this is a dummy instruction
+    inst->setTid(tid);        
     resPool->scheduleEvent(c_event, inst, 0, 0, tid);
 }
 
@@ -644,9 +663,38 @@
 
 
 void
+InOrderCPU::activateNextReadyThread()
+{
+    if (readyThreads.size() >= 1) {          
+        ThreadID ready_tid = readyThreads.front();
+        
+        // Activate in Pipeline
+        activateThread(ready_tid);                        
+        
+        // Activate in Resource Pool
+        resPool->activateAll(ready_tid);
+        
+        list<ThreadID>::iterator ready_it =
+            std::find(readyThreads.begin(), readyThreads.end(), ready_tid);
+        readyThreads.erase(ready_it);                        
+    } else {
+        DPRINTF(InOrderCPU,
+                "No Ready Threads to Activate.\n");
+    }        
+}
+
+void
 InOrderCPU::activateThread(ThreadID tid)
 {
-    if (!isThreadActive(tid)) {
+    if (threadModel == SwitchOnCacheMiss &&
+        numActiveThreads() == 1) {
+        DPRINTF(InOrderCPU,
+                "Ignoring Activation of [tid:%i]. Placing on "
+                "ready list\n", tid);        
+
+        readyThreads.push_back(tid);
+        
+    } else if (!isThreadActive(tid)) {
         DPRINTF(InOrderCPU,
                 "Adding Thread %i to active threads list in CPU.\n", tid);
         activeThreads.push_back(tid);
@@ -892,6 +940,23 @@
     _status = Running;
 }
 
+void
+InOrderCPU::activateNextReadyContext(int delay)
+{
+    DPRINTF(InOrderCPU,"Activating next ready thread\n");
+
+    // NOTE: Add 5 to the event priority so that we always activate
+    // threads after we've finished deactivating, squashing,etc.
+    // other threads
+    scheduleCpuEvent(ActivateNextReadyThread, NoFault, 0/*tid*/, dummyInst, 
+                     delay, 5);
+
+    // Be sure to signal that there's some activity so the CPU doesn't
+    // deschedule itself.
+    activityRec.activity();
+
+    _status = Running;
+}
 
 void
 InOrderCPU::suspendContext(ThreadID tid, int delay)
@@ -903,8 +968,9 @@
 void
 InOrderCPU::suspendThread(ThreadID tid)
 {
-    DPRINTF(InOrderCPU,"[tid: %i]: Suspended ...\n", tid);
+    DPRINTF(InOrderCPU, "[tid: %i]: Placing on Suspended Threads List...\n", 
tid);
     deactivateThread(tid);
+    suspendedThreads.push_back(tid);    
 }
 
 void
diff -r d807273f17c0 -r 099ca6d9fc03 src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh    Sun Jan 31 18:26:26 2010 -0500
+++ b/src/cpu/inorder/cpu.hh    Sun Jan 31 18:26:32 2010 -0500
@@ -89,7 +89,7 @@
     typedef TimeBuffer<InterStageStruct> StageQueue;
 
     friend class Resource;
-
+    
   public:
     /** Constructs a CPU with the given parameters. */
     InOrderCPU(Params *params);
@@ -175,6 +175,8 @@
     // pool event.
     enum CPUEventType {
         ActivateThread,
+        ActivateNextReadyThread,
+        DeactivateThread,
         DeallocateThread,
         SuspendThread,
         DisableThreads,
@@ -361,6 +363,10 @@
     void activateContext(ThreadID tid, int delay = 0);
     void activateThread(ThreadID tid);
 
+    /** Add Thread to Active Threads List. */
+    void activateNextReadyContext(int delay = 0);
+    void activateNextReadyThread();
+
     /** Remove Thread from Active Threads List */
     void suspendContext(ThreadID tid, int delay = 0);
     void suspendThread(ThreadID tid);
@@ -612,6 +618,9 @@
     /** Current Threads List */
     std::list<ThreadID> currentThreads;
 
+    /** Ready Threads List */
+    std::list<ThreadID> readyThreads;
+
     /** Suspended Threads List */
     std::list<ThreadID> suspendedThreads;
 
@@ -633,6 +642,18 @@
     /** Number of Active Threads in the CPU */
     ThreadID numActiveThreads() { return activeThreads.size(); }
 
+    /** Thread id of active thread
+     *  Only used for SwitchOnCacheMiss model. Assumes only 1 thread active
+     */
+    ThreadID activeThreadId() 
+    { 
+        if (numActiveThreads() > 0)
+            return activeThreads.front();
+        else
+            return -1;
+    }
+    
+     
     /** Records that there was time buffer activity this cycle. */
     void activityThisCycle() { activityRec.activity(); }
 
diff -r d807273f17c0 -r 099ca6d9fc03 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:26:26 2010 -0500
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:26:32 2010 -0500
@@ -951,7 +951,15 @@
                     // Remove Thread From Pipeline & Resource Pool
                     inst->squashingStage = stageNum;         
                     inst->bdelaySeqNum = inst->seqNum;                         
      
-                    cpu->squashFromMemStall(inst, tid);                    
+                    cpu->squashFromMemStall(inst, tid);  
+
+                    // Switch On Cache Miss
+                    //=====================
+                    // Suspend Thread at end of cycle
+                    cpu->suspendContext(tid);                    
+
+                    // Activate Next Ready Thread at end of cycle
+                    cpu->activateNextReadyContext();                           
                                                                    
                 }
                 
                 break;
diff -r d807273f17c0 -r 099ca6d9fc03 src/cpu/inorder/resource_pool.cc
--- a/src/cpu/inorder/resource_pool.cc  Sun Jan 31 18:26:26 2010 -0500
+++ b/src/cpu/inorder/resource_pool.cc  Sun Jan 31 18:26:32 2010 -0500
@@ -212,7 +212,8 @@
       case InOrderCPU::ActivateThread:
         {
             DPRINTF(Resource, "Scheduling Activate Thread Resource Pool Event "
-                    "for tick %i.\n", curTick + delay);
+                    "for tick %i, [tid:%i].\n", curTick + delay, 
+                    inst->readTid());
             ResPoolEvent *res_pool_event = 
                 new ResPoolEvent(this,
                                  e_type,
@@ -295,7 +296,6 @@
       default:
         DPRINTF(Resource, "Ignoring Unrecognized CPU Event (%s).\n", 
                 InOrderCPU::eventNames[e_type]);
-        ; // If Resource Pool doesnt recognize event, we ignore it.
     }
 }
 
@@ -310,7 +310,7 @@
                         InstSeqNum done_seq_num, ThreadID tid)
 {
     DPRINTF(Resource, "[tid:%i] Stage %i squashing all instructions above "
-            "[sn:%i].\n", stage_num, tid, done_seq_num);
+            "[sn:%i].\n", tid, stage_num, done_seq_num);
 
     int num_resources = resources.size();
 
@@ -337,14 +337,24 @@
 void
 ResourcePool::activateAll(ThreadID tid)
 {
-    DPRINTF(Resource, "[tid:%i] Broadcasting Thread Activation to all "
-            "resources.\n", tid);
-
-    int num_resources = resources.size();
-
-    for (int idx = 0; idx < num_resources; idx++) {
-        resources[idx]->activateThread(tid);
-    }
+    bool do_activate = cpu->threadModel != InOrderCPU::SwitchOnCacheMiss ||
+        cpu->numActiveThreads() < 1 ||
+        cpu->activeThreadId() == tid;
+    
+        
+    if (do_activate) {
+        DPRINTF(Resource, "[tid:%i] Broadcasting Thread Activation to all "
+                    "resources.\n", tid);
+ 
+        int num_resources = resources.size();
+ 
+        for (int idx = 0; idx < num_resources; idx++) {
+            resources[idx]->activateThread(tid);
+        }
+    } else {
+        DPRINTF(Resource, "[tid:%i] Ignoring Thread Activation to all "
+                    "resources.\n", tid);
+     }
 }
 
 void
@@ -374,7 +384,7 @@
 }
 
 ResourcePool::ResPoolEvent::ResPoolEvent(ResourcePool *_resPool)
-    : Event(CPU_Tick_Pri), resPool(_resPool),
+    : Event((Event::Priority)((unsigned)CPU_Tick_Pri+5)), resPool(_resPool),
       eventType((InOrderCPU::CPUEventType) Default)
 { }
 
diff -r d807273f17c0 -r 099ca6d9fc03 src/cpu/inorder/thread_context.cc
--- a/src/cpu/inorder/thread_context.cc Sun Jan 31 18:26:26 2010 -0500
+++ b/src/cpu/inorder/thread_context.cc Sun Jan 31 18:26:32 2010 -0500
@@ -242,21 +242,21 @@
 void
 InOrderThreadContext::setPC(uint64_t val)
 {
-    DPRINTF(InOrderCPU, "Setting PC to %08p\n", val);
+    DPRINTF(InOrderCPU, "[tid:%i] Setting PC to %08p\n", thread->readTid(), 
val);
     cpu->setPC(val, thread->readTid());
 }
 
 void
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to