From 7b3b362ba5d2690324abd58c883fd1d5fe4dc767 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 17:18:15 -0500 Subject: inorder: init internal debug cpu counters - cpuEventNum - resReqCount --- src/cpu/inorder/cpu.cc | 60 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 1e3fdc40e..38f6b4eed 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -115,7 +115,8 @@ InOrderCPU::CPUEvent::process() cpu->activateThread(tid); break; - //@TODO: Consider Implementing "Suspend Thread" as Separate from Deallocate + //@TODO: Consider Implementing "Suspend Thread" as Separate from + //Deallocate case SuspendThread: // Suspend & Deallocate are same for now. //cpu->suspendThread(tid); //break; @@ -145,11 +146,14 @@ InOrderCPU::CPUEvent::process() default: fatal("Unrecognized Event Type %d", cpuEventType); + } - + cpu->cpuEventRemoveList.push(this); } + + const char * InOrderCPU::CPUEvent::description() { @@ -185,6 +189,10 @@ InOrderCPU::InOrderCPU(Params *params) system(params->system), physmem(system->physmem), #endif // FULL_SYSTEM +#ifdef DEBUG + cpuEventNum(0), + resReqCount(0), +#endif // DEBUG switchCount(0), deferRegistration(false/*params->deferRegistration*/), stageTracing(params->stageTracing), @@ -301,7 +309,7 @@ InOrderCPU::InOrderCPU(Params *params) // Define dummy instructions and resource requests to be used. DynInstPtr dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0); - dummyReq = new ResourceRequest(NULL, NULL, 0, 0, 0, 0); + dummyReq = new ResourceRequest(resPool->getResource(0), NULL, 0, 0, 0, 0); // Reset CPU to reset state. #if FULL_SYSTEM @@ -322,6 +330,13 @@ InOrderCPU::regStats() /* Register the Resource Pool's stats here.*/ resPool->regStats(); +#ifdef DEBUG + maxResReqCount + .name(name() + ".maxResReqCount") + .desc("Maximum number of live resource requests in CPU") + .prereq(maxResReqCount); +#endif + /* Register any of the InOrderCPU's stats here.*/ timesIdled .name(name() + ".timesIdled") @@ -342,7 +357,7 @@ InOrderCPU::regStats() smtCycles .name(name() + ".smtCycles") - .desc("Total number of cycles that the CPU was simultaneous multithreading.(SMT)"); + .desc("Total number of cycles that the CPU was in SMT-mode"); committedInsts .init(numThreads) @@ -435,7 +450,8 @@ InOrderCPU::tick() //Tick next_tick = curTick + cycles(1); //tickEvent.schedule(next_tick); mainEventQueue.schedule(&tickEvent, nextCycle(curTick + 1)); - DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle(curTick + 1)); + DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", + nextCycle(curTick + 1)); } } @@ -640,8 +656,8 @@ void InOrderCPU::addToCurrentThreads(ThreadID tid) { if (!isThreadInCPU(tid)) { - DPRINTF(InOrderCPU, "Adding Thread %i to current threads list in CPU.\n", - tid); + DPRINTF(InOrderCPU, "Adding Thread %i to current threads list in CPU." + "\n", tid); currentThreads.push_back(tid); } } @@ -1002,9 +1018,11 @@ InOrderCPU::readRegOtherThread(unsigned reg_idx, ThreadID tid) tid = TheISA::getTargetThread(tcBase(tid)); } - if (reg_idx < FP_Base_DepTag) { // Integer Register File + if (reg_idx < FP_Base_DepTag) { + // Integer Register File return readIntReg(reg_idx, tid); - } else if (reg_idx < Ctrl_Base_DepTag) { // Float Register File + } else if (reg_idx < Ctrl_Base_DepTag) { + // Float Register File reg_idx -= FP_Base_DepTag; return readFloatRegBits(reg_idx, tid); } else { @@ -1070,9 +1088,12 @@ InOrderCPU::addInst(DynInstPtr &inst) void InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) { - // Set the CPU's PCs - This contributes to the precise state of the CPU which can be used - // when restoring a thread to the CPU after a fork or after an exception - // @TODO: Set-Up Grad-Info/Committed-Info to let ThreadState know if it's a branch or not + // Set the CPU's PCs - This contributes to the precise state of the CPU + // which can be used when restoring a thread to the CPU after a fork or + // after an exception + // ================= + // @TODO: Set-Up Grad-Info/Committed-Info to let ThreadState know if + // it's a branch or not setPC(inst->readPC(), tid); setNextPC(inst->readNextPC(), tid); setNextNPC(inst->readNextNPC(), tid); @@ -1112,7 +1133,8 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) // Broadcast to other resources an instruction // has been completed - resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst, tid); + resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst, + tid); // Finally, remove instruction from CPU removeInst(inst); @@ -1380,7 +1402,8 @@ InOrderCPU::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) { //@TODO: Generalize name "CacheUnit" to "MemUnit" just in case // you want to run w/out caches? - CacheUnit *cache_res = dynamic_cast(resPool->getResource(dataPortIdx)); + CacheUnit *cache_res = + dynamic_cast(resPool->getResource(dataPortIdx)); return cache_res->read(inst, addr, data, flags); } @@ -1483,14 +1506,16 @@ InOrderCPU::write(DynInstPtr inst, uint8_t data, Addr addr, template<> Fault -InOrderCPU::write(DynInstPtr inst, double data, Addr addr, unsigned flags, uint64_t *res) +InOrderCPU::write(DynInstPtr inst, double data, Addr addr, unsigned flags, + uint64_t *res) { return write(inst, *(uint64_t*)&data, addr, flags, res); } template<> Fault -InOrderCPU::write(DynInstPtr inst, float data, Addr addr, unsigned flags, uint64_t *res) +InOrderCPU::write(DynInstPtr inst, float data, Addr addr, unsigned flags, + uint64_t *res) { return write(inst, *(uint32_t*)&data, addr, flags, res); } @@ -1498,7 +1523,8 @@ InOrderCPU::write(DynInstPtr inst, float data, Addr addr, unsigned flags, uint64 template<> Fault -InOrderCPU::write(DynInstPtr inst, int32_t data, Addr addr, unsigned flags, uint64_t *res) +InOrderCPU::write(DynInstPtr inst, int32_t data, Addr addr, unsigned flags, + uint64_t *res) { return write(inst, (uint32_t)data, addr, flags, res); } -- cgit v1.2.3 From 0e96798fe0a56936f8590dbd301f2b07a1850e22 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:25:13 -0500 Subject: configs/inorder: add options for switch-on-miss to inorder cpu --- src/cpu/inorder/cpu.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 38f6b4eed..a1e6c9c86 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -197,7 +197,7 @@ InOrderCPU::InOrderCPU(Params *params) deferRegistration(false/*params->deferRegistration*/), stageTracing(params->stageTracing), numVirtProcs(1) -{ +{ ThreadID active_threads; cpu_params = params; @@ -216,6 +216,15 @@ InOrderCPU::InOrderCPU(Params *params) "in your InOrder implementation or " "edit your workload size."); } + + if (active_threads > 1) { + threadModel = (InOrderCPU::ThreadModel) params->threadModel; + } else { + threadModel = Single; + } + + + #endif // Bind the fetch & data ports from the resource pool. -- cgit v1.2.3 From d8e0935af2805bc2c4bdfbab7de2c63f7fde46f7 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:26:03 -0500 Subject: inorder: add insts to cpu event some events are going to need instruction data when they process, so just include the instruction in the event construction --- src/cpu/inorder/cpu.cc | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index a1e6c9c86..69aea0c57 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -84,10 +84,10 @@ InOrderCPU::TickEvent::description() } InOrderCPU::CPUEvent::CPUEvent(InOrderCPU *_cpu, CPUEventType e_type, - Fault fault, ThreadID _tid, unsigned _vpe) + Fault fault, ThreadID _tid, DynInstPtr inst) : Event(CPU_Tick_Pri), cpu(_cpu) { - setEvent(e_type, fault, _tid, _vpe); + setEvent(e_type, fault, _tid, inst); } @@ -317,7 +317,7 @@ InOrderCPU::InOrderCPU(Params *params) contextSwitch = false; // Define dummy instructions and resource requests to be used. - DynInstPtr dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0); + dummyInst = new InOrderDynInst(this, NULL, 0, 0); dummyReq = new ResourceRequest(resPool->getResource(0), NULL, 0, 0, 0, 0); // Reset CPU to reset state. @@ -570,7 +570,7 @@ void InOrderCPU::trap(Fault fault, ThreadID tid, int delay) { //@ Squash Pipeline during TRAP - scheduleCpuEvent(Trap, fault, tid, 0/*vpe*/, delay); + scheduleCpuEvent(Trap, fault, tid, dummyInst, delay); } void @@ -581,9 +581,10 @@ InOrderCPU::trapCPU(Fault fault, ThreadID tid) void InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault, - ThreadID tid, unsigned vpe, unsigned delay) + ThreadID tid, DynInstPtr inst, + unsigned delay) { - CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, vpe); + CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, inst); if (delay >= 0) { DPRINTF(InOrderCPU, "Scheduling CPU Event (%s) for cycle %i.\n", @@ -597,7 +598,7 @@ InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault, // Broadcast event to the Resource Pool DynInstPtr dummy_inst = new InOrderDynInst(this, NULL, getNextEventNum(), tid); - resPool->scheduleEvent(c_event, dummy_inst, 0, 0, tid); + resPool->scheduleEvent(c_event, inst, 0, 0, tid); } inline bool @@ -699,7 +700,7 @@ InOrderCPU::enableVirtProcElement(unsigned vpe) "Enabling of concurrent virtual processor execution", vpe); - scheduleCpuEvent(EnableVPEs, NoFault, 0/*tid*/, vpe); + scheduleCpuEvent(EnableVPEs, NoFault, 0/*tid*/, dummyInst); } void @@ -725,7 +726,7 @@ InOrderCPU::disableVirtProcElement(ThreadID tid, unsigned vpe) "Disabling of concurrent virtual processor execution", vpe); - scheduleCpuEvent(DisableVPEs, NoFault, 0/*tid*/, vpe); + scheduleCpuEvent(DisableVPEs, NoFault, 0/*tid*/, dummyInst); } void @@ -759,7 +760,7 @@ InOrderCPU::enableMultiThreading(unsigned vpe) DPRINTF(InOrderCPU, "[vpe:%i]: Scheduling Enable Multithreading on " "virtual processor %i", vpe); - scheduleCpuEvent(EnableThreads, NoFault, 0/*tid*/, vpe); + scheduleCpuEvent(EnableThreads, NoFault, 0/*tid*/, dummyInst); } void @@ -786,7 +787,7 @@ InOrderCPU::disableMultiThreading(ThreadID tid, unsigned vpe) DPRINTF(InOrderCPU, "[tid:%i]: Scheduling Disable Multithreading on " "virtual processor %i", tid, vpe); - scheduleCpuEvent(DisableThreads, NoFault, tid, vpe); + scheduleCpuEvent(DisableThreads, NoFault, tid, dummyInst); } void @@ -850,7 +851,7 @@ InOrderCPU::activateContext(ThreadID tid, int delay) { DPRINTF(InOrderCPU,"[tid:%i]: Activating ...\n", tid); - scheduleCpuEvent(ActivateThread, NoFault, tid, 0/*vpe*/, delay); + scheduleCpuEvent(ActivateThread, NoFault, tid, dummyInst, delay); // Be sure to signal that there's some activity so the CPU doesn't // deschedule itself. @@ -863,7 +864,7 @@ InOrderCPU::activateContext(ThreadID tid, int delay) void InOrderCPU::suspendContext(ThreadID tid, int delay) { - scheduleCpuEvent(SuspendThread, NoFault, tid, 0/*vpe*/, delay); + scheduleCpuEvent(SuspendThread, NoFault, tid, dummyInst, delay); //_status = Idle; } @@ -877,7 +878,7 @@ InOrderCPU::suspendThread(ThreadID tid) void InOrderCPU::deallocateContext(ThreadID tid, int delay) { - scheduleCpuEvent(DeallocateThread, NoFault, tid, 0/*vpe*/, delay); + scheduleCpuEvent(DeallocateThread, NoFault, tid, dummyInst, delay); } void -- cgit v1.2.3 From eac5eac67ae8076e934d78063a24eeef08f25413 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:26:13 -0500 Subject: 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 --- src/cpu/inorder/cpu.cc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 69aea0c57..035aa0571 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -140,6 +140,10 @@ InOrderCPU::CPUEvent::process() 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 @@ InOrderCPU::trapCPU(Fault fault, ThreadID tid) 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, -- cgit v1.2.3 From 4a945aab1958d39fcfea4608715e77d5112809cf Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:26:26 -0500 Subject: inorder: add event priority offset allow for events to schedule themselves later if desired. this is important because of cases like where you need to activate a thread only after the previous thread has been deactivated. The ordering there has to be enforced --- src/cpu/inorder/cpu.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 035aa0571..c0daad207 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -84,8 +84,10 @@ InOrderCPU::TickEvent::description() } InOrderCPU::CPUEvent::CPUEvent(InOrderCPU *_cpu, CPUEventType e_type, - Fault fault, ThreadID _tid, DynInstPtr inst) - : Event(CPU_Tick_Pri), cpu(_cpu) + Fault fault, ThreadID _tid, DynInstPtr inst, + unsigned event_pri_offset) + : Event(Event::Priority((unsigned int)CPU_Tick_Pri + event_pri_offset)), + cpu(_cpu) { setEvent(e_type, fault, _tid, inst); } @@ -611,13 +613,14 @@ InOrderCPU::squashDueToMemStall(int stage_num, InstSeqNum seq_num, ThreadID tid) void InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault, ThreadID tid, DynInstPtr inst, - unsigned delay) + unsigned delay, unsigned event_pri_offset) { - CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, inst); + CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, inst, + event_pri_offset); if (delay >= 0) { - DPRINTF(InOrderCPU, "Scheduling CPU Event (%s) for cycle %i.\n", - eventNames[c_event], curTick + delay); + DPRINTF(InOrderCPU, "Scheduling CPU Event (%s) for cycle %i, [tid:%i].\n", + eventNames[c_event], curTick + delay, tid); mainEventQueue.schedule(cpu_event,curTick + delay); } else { cpu_event->process(); -- cgit v1.2.3 From e1fcc6498017574735362636791f9ad73fb39b04 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:26:32 -0500 Subject: 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 --- src/cpu/inorder/cpu.cc | 78 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 6 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index c0daad207..e52e5935a 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -96,6 +96,8 @@ InOrderCPU::CPUEvent::CPUEvent(InOrderCPU *_cpu, CPUEventType e_type, std::string InOrderCPU::eventNames[NumCPUEvents] = { "ActivateThread", + "ActivateNextReadyThread", + "DeactivateThread", "DeallocateThread", "SuspendThread", "DisableThreads", @@ -119,9 +121,18 @@ InOrderCPU::CPUEvent::process() //@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 @@ InOrderCPU::InOrderCPU(Params *params) 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 @@ InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault, } // 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); } @@ -643,10 +662,39 @@ InOrderCPU::isThreadActive(ThreadID tid) } +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::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 @@ InOrderCPU::activateContext(ThreadID tid, int delay) _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 @@ InOrderCPU::suspendContext(ThreadID tid, int delay) 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 -- cgit v1.2.3 From d9eaa2fe2149528e109b8b32a00dd4fa72d8ec4f Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:26:40 -0500 Subject: inorder-cleanup: remove unused thread functions --- src/cpu/inorder/cpu.cc | 278 ++++++++++--------------------------------------- 1 file changed, 54 insertions(+), 224 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index e52e5935a..954309a74 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -100,13 +100,9 @@ std::string InOrderCPU::eventNames[NumCPUEvents] = "DeactivateThread", "DeallocateThread", "SuspendThread", - "DisableThreads", - "EnableThreads", - "DisableVPEs", - "EnableVPEs", "Trap", "InstGraduated", - "SquashAll", + "SquashFromMemStall", "UpdatePCs" }; @@ -119,8 +115,6 @@ InOrderCPU::CPUEvent::process() cpu->activateThread(tid); break; - //@TODO: Consider Implementing "Suspend Thread" as Separate from - //Deallocate case ActivateNextReadyThread: cpu->activateNextReadyThread(); break; @@ -129,28 +123,12 @@ InOrderCPU::CPUEvent::process() cpu->deactivateThread(tid); break; - case SuspendThread: // Suspend & Deallocate are same for now. - cpu->suspendThread(tid); - break; - case DeallocateThread: cpu->deallocateThread(tid); break; - case EnableVPEs: - cpu->enableVPEs(vpe); - break; - - case DisableVPEs: - cpu->disableVPEs(tid, vpe); - break; - - case EnableThreads: - cpu->enableThreads(vpe); - break; - - case DisableThreads: - cpu->disableThreads(tid, vpe); + case SuspendThread: + cpu->suspendThread(tid); break; case SquashFromMemStall: @@ -212,8 +190,7 @@ InOrderCPU::InOrderCPU(Params *params) #endif // DEBUG switchCount(0), deferRegistration(false/*params->deferRegistration*/), - stageTracing(params->stageTracing), - numVirtProcs(1) + stageTracing(params->stageTracing) { ThreadID active_threads; cpu_params = params; @@ -335,11 +312,10 @@ InOrderCPU::InOrderCPU(Params *params) memset(floatRegs.i[tid], 0, sizeof(floatRegs.i[tid])); isa[tid].clear(); - isa[tid].expandForMultithreading(numThreads, numVirtProcs); + isa[tid].expandForMultithreading(numThreads, 1/*numVirtProcs*/); } lastRunningCycle = curTick; - contextSwitch = false; // Define dummy instructions and resource requests to be used. dummyInst = new InOrderDynInst(this, NULL, 0, 0); @@ -526,7 +502,7 @@ InOrderCPU::reset() { for (int i = 0; i < numThreads; i++) { isa[i].reset(coreType, numThreads, - numVirtProcs, dynamic_cast(this)); + 1/*numVirtProcs*/, dynamic_cast(this)); } } @@ -703,6 +679,20 @@ InOrderCPU::activateThread(ThreadID tid) } } +void +InOrderCPU::deactivateContext(ThreadID tid, int delay) +{ + DPRINTF(InOrderCPU,"[tid:%i]: Deactivating ...\n", tid); + + scheduleCpuEvent(DeactivateThread, NoFault, tid, dummyInst, delay); + + // Be sure to signal that there's some activity so the CPU doesn't + // deschedule itself. + activityRec.activity(); + + _status = Running; +} + void InOrderCPU::deactivateThread(ThreadID tid) { @@ -723,173 +713,58 @@ InOrderCPU::deactivateThread(ThreadID tid) } void -InOrderCPU::removePipelineStalls(ThreadID tid) -{ - DPRINTF(InOrderCPU,"[tid:%i]: Removing all pipeline stalls\n", - tid); - - for (int stNum = 0; stNum < NumStages ; stNum++) { - pipelineStage[stNum]->removeStalls(tid); - } - -} -bool -InOrderCPU::isThreadInCPU(ThreadID tid) -{ - list::iterator isCurrent = - std::find(currentThreads.begin(), currentThreads.end(), tid); - - return (isCurrent != currentThreads.end()); -} - -void -InOrderCPU::addToCurrentThreads(ThreadID tid) -{ - if (!isThreadInCPU(tid)) { - DPRINTF(InOrderCPU, "Adding Thread %i to current threads list in CPU." - "\n", tid); - currentThreads.push_back(tid); - } -} - -void -InOrderCPU::removeFromCurrentThreads(ThreadID tid) -{ - if (isThreadInCPU(tid)) { - DPRINTF(InOrderCPU, - "Adding Thread %i to current threads list in CPU.\n", tid); - list::iterator isCurrent = - std::find(currentThreads.begin(), currentThreads.end(), tid); - currentThreads.erase(isCurrent); - } -} - -bool -InOrderCPU::isThreadSuspended(ThreadID tid) -{ - list::iterator isSuspended = - std::find(suspendedThreads.begin(), suspendedThreads.end(), tid); - - return (isSuspended!= suspendedThreads.end()); -} - -void -InOrderCPU::enableVirtProcElement(unsigned vpe) -{ - DPRINTF(InOrderCPU, "[vpe:%i]: Scheduling " - "Enabling of concurrent virtual processor execution", - vpe); - - scheduleCpuEvent(EnableVPEs, NoFault, 0/*tid*/, dummyInst); -} - -void -InOrderCPU::enableVPEs(unsigned vpe) +InOrderCPU::deallocateContext(ThreadID tid, int delay) { - DPRINTF(InOrderCPU, "[vpe:%i]: Enabling Concurrent Execution " - "virtual processors %i", vpe); - - list::iterator thread_it = currentThreads.begin(); + DPRINTF(InOrderCPU,"[tid:%i]: Deallocating ...\n", tid); - while (thread_it != currentThreads.end()) { - if (!isThreadSuspended(*thread_it)) { - activateThread(*thread_it); - } - thread_it++; - } -} + scheduleCpuEvent(DeallocateThread, NoFault, tid, dummyInst, delay); -void -InOrderCPU::disableVirtProcElement(ThreadID tid, unsigned vpe) -{ - DPRINTF(InOrderCPU, "[vpe:%i]: Scheduling " - "Disabling of concurrent virtual processor execution", - vpe); + // Be sure to signal that there's some activity so the CPU doesn't + // deschedule itself. + activityRec.activity(); - scheduleCpuEvent(DisableVPEs, NoFault, 0/*tid*/, dummyInst); + _status = Running; } void -InOrderCPU::disableVPEs(ThreadID tid, unsigned vpe) +InOrderCPU::deallocateThread(ThreadID tid) { - DPRINTF(InOrderCPU, "[vpe:%i]: Disabling Concurrent Execution of " - "virtual processors %i", vpe); + DPRINTF(InOrderCPU, "[tid:%i]: Calling deallocate thread.\n", tid); - unsigned base_vpe = TheISA::getVirtProcNum(tcBase(tid)); - - list::iterator thread_it = activeThreads.begin(); - - vector::iterator> removeList; + if (isThreadActive(tid)) { + DPRINTF(InOrderCPU,"[tid:%i]: Removing from active threads list\n", + tid); + list::iterator thread_it = + std::find(activeThreads.begin(), activeThreads.end(), tid); - while (thread_it != activeThreads.end()) { - if (base_vpe != vpe) { - removeList.push_back(thread_it); - } - thread_it++; - } + removePipelineStalls(*thread_it); - for (int i = 0; i < removeList.size(); i++) { - activeThreads.erase(removeList[i]); + activeThreads.erase(thread_it); } -} -void -InOrderCPU::enableMultiThreading(unsigned vpe) -{ - // Schedule event to take place at end of cycle - DPRINTF(InOrderCPU, "[vpe:%i]: Scheduling Enable Multithreading on " - "virtual processor %i", vpe); - - scheduleCpuEvent(EnableThreads, NoFault, 0/*tid*/, dummyInst); + // TODO: "Un"Load/Unmap register file state + } void -InOrderCPU::enableThreads(unsigned vpe) +InOrderCPU::removePipelineStalls(ThreadID tid) { - DPRINTF(InOrderCPU, "[vpe:%i]: Enabling Multithreading on " - "virtual processor %i", vpe); - - list::iterator thread_it = currentThreads.begin(); + DPRINTF(InOrderCPU,"[tid:%i]: Removing all pipeline stalls\n", + tid); - while (thread_it != currentThreads.end()) { - if (TheISA::getVirtProcNum(tcBase(*thread_it)) == vpe) { - if (!isThreadSuspended(*thread_it)) { - activateThread(*thread_it); - } - } - thread_it++; + for (int stNum = 0; stNum < NumStages ; stNum++) { + pipelineStage[stNum]->removeStalls(tid); } -} -void -InOrderCPU::disableMultiThreading(ThreadID tid, unsigned vpe) -{ - // Schedule event to take place at end of cycle - DPRINTF(InOrderCPU, "[tid:%i]: Scheduling Disable Multithreading on " - "virtual processor %i", tid, vpe); - scheduleCpuEvent(DisableThreads, NoFault, tid, dummyInst); } -void -InOrderCPU::disableThreads(ThreadID tid, unsigned vpe) +bool +InOrderCPU::isThreadSuspended(ThreadID tid) { - DPRINTF(InOrderCPU, "[tid:%i]: Disabling Multithreading on " - "virtual processor %i", tid, vpe); - - list::iterator thread_it = activeThreads.begin(); - - vector::iterator> removeList; - - while (thread_it != activeThreads.end()) { - if (TheISA::getVirtProcNum(tcBase(*thread_it)) == vpe) { - removeList.push_back(thread_it); - } - thread_it++; - } + list::iterator isSuspended = + std::find(suspendedThreads.begin(), suspendedThreads.end(), tid); - for (int i = 0; i < removeList.size(); i++) { - activeThreads.erase(removeList[i]); - } + return (isSuspended!= suspendedThreads.end()); } void @@ -958,6 +833,12 @@ InOrderCPU::activateNextReadyContext(int delay) _status = Running; } +void +InOrderCPU::haltContext(ThreadID tid, int delay) +{ + suspendContext(tid, delay); +} + void InOrderCPU::suspendContext(ThreadID tid, int delay) { @@ -973,24 +854,6 @@ InOrderCPU::suspendThread(ThreadID tid) suspendedThreads.push_back(tid); } -void -InOrderCPU::deallocateContext(ThreadID tid, int delay) -{ - scheduleCpuEvent(DeallocateThread, NoFault, tid, dummyInst, delay); -} - -void -InOrderCPU::deallocateThread(ThreadID tid) -{ - DPRINTF(InOrderCPU,"[tid:%i]: Deallocating ...", tid); - - removeFromCurrentThreads(tid); - - deactivateThread(tid); - - squashThreadInPipeline(tid); -} - void InOrderCPU::squashThreadInPipeline(ThreadID tid) { @@ -1000,45 +863,12 @@ InOrderCPU::squashThreadInPipeline(ThreadID tid) } } -void -InOrderCPU::haltContext(ThreadID tid, int delay) -{ - DPRINTF(InOrderCPU, "[tid:%i]: Halt context called.\n", tid); - - // Halt is same thing as deallocate for now - // @TODO: Differentiate between halt & deallocate in the CPU - // model - deallocateContext(tid, delay); -} - -void -InOrderCPU::insertThread(ThreadID tid) -{ - panic("Unimplemented Function\n."); -} - -void -InOrderCPU::removeThread(ThreadID tid) -{ - DPRINTF(InOrderCPU, "Removing Thread %i from CPU.\n", tid); - - /** Broadcast to CPU resources*/ -} - PipelineStage* InOrderCPU::getPipeStage(int stage_num) { return pipelineStage[stage_num]; } - -void -InOrderCPU::activateWhenReady(ThreadID tid) -{ - panic("Unimplemented Function\n."); -} - - uint64_t InOrderCPU::readPC(ThreadID tid) { -- cgit v1.2.3 From 96b493d3159f7e94b8e53edbe562e28076f2af95 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:26:47 -0500 Subject: inorder: ready/suspend status fns update/add in the use of isThreadReady & isThreadSuspended functions.Check in activateThread what list a thread is on so it can be managed accordingly. --- src/cpu/inorder/cpu.cc | 56 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 16 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 954309a74..ec6bb21ee 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -628,7 +628,7 @@ InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault, resPool->scheduleEvent(c_event, inst, 0, 0, tid); } -inline bool +bool InOrderCPU::isThreadActive(ThreadID tid) { list::iterator isActive = @@ -637,6 +637,23 @@ InOrderCPU::isThreadActive(ThreadID tid) return (isActive != activeThreads.end()); } +bool +InOrderCPU::isThreadReady(ThreadID tid) +{ + list::iterator isReady = + std::find(readyThreads.begin(), readyThreads.end(), tid); + + return (isReady != readyThreads.end()); +} + +bool +InOrderCPU::isThreadSuspended(ThreadID tid) +{ + list::iterator isSuspended = + std::find(suspendedThreads.begin(), suspendedThreads.end(), tid); + + return (isSuspended != suspendedThreads.end()); +} void InOrderCPU::activateNextReadyThread() @@ -655,26 +672,40 @@ InOrderCPU::activateNextReadyThread() readyThreads.erase(ready_it); } else { DPRINTF(InOrderCPU, - "No Ready Threads to Activate.\n"); + "Attempting to activate new thread, but No Ready Threads to" + "activate.\n"); } } void InOrderCPU::activateThread(ThreadID tid) { + if (isThreadSuspended(tid)) { + DPRINTF(InOrderCPU, + "Removing [tid:%i] from suspended threads list.\n", tid); + + list::iterator susp_it = + std::find(suspendedThreads.begin(), suspendedThreads.end(), + tid); + suspendedThreads.erase(susp_it); + } + if (threadModel == SwitchOnCacheMiss && numActiveThreads() == 1) { DPRINTF(InOrderCPU, - "Ignoring Activation of [tid:%i]. Placing on " - "ready list\n", tid); + "Ignoring activation of [tid:%i], since [tid:%i] is " + "already running.\n", tid, activeThreadId()); + + DPRINTF(InOrderCPU,"Placing [tid:%i] ready threads list\n", + tid); readyThreads.push_back(tid); - } else if (!isThreadActive(tid)) { + } else if (!isThreadActive(tid)) { DPRINTF(InOrderCPU, - "Adding Thread %i to active threads list in CPU.\n", tid); + "Adding [tid:%i] to active threads list.\n", tid); activeThreads.push_back(tid); - + wakeCPU(); } } @@ -710,6 +741,8 @@ InOrderCPU::deactivateThread(ThreadID tid) activeThreads.erase(thread_it); } + + assert(!isThreadActive(tid)); } void @@ -758,15 +791,6 @@ InOrderCPU::removePipelineStalls(ThreadID tid) } -bool -InOrderCPU::isThreadSuspended(ThreadID tid) -{ - list::iterator isSuspended = - std::find(suspendedThreads.begin(), suspendedThreads.end(), tid); - - return (isSuspended!= suspendedThreads.end()); -} - void InOrderCPU::updateThreadPriority() { -- cgit v1.2.3 From 90d3b45a566847fe15095b92238e32973ad9cc0e Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:27:38 -0500 Subject: inorder: ready thread wakeup allow a thread to wakeup and be activated after it has been in suspended state and another thread is switched out. Need to give pipeline stages a "activateThread" function so that can get to their suspended instruction when the time is right. --- src/cpu/inorder/cpu.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index ec6bb21ee..501150386 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -674,6 +674,8 @@ InOrderCPU::activateNextReadyThread() DPRINTF(InOrderCPU, "Attempting to activate new thread, but No Ready Threads to" "activate.\n"); + DPRINTF(InOrderCPU, + "Unable to switch to next active thread.\n"); } } @@ -696,7 +698,7 @@ InOrderCPU::activateThread(ThreadID tid) "Ignoring activation of [tid:%i], since [tid:%i] is " "already running.\n", tid, activeThreadId()); - DPRINTF(InOrderCPU,"Placing [tid:%i] ready threads list\n", + DPRINTF(InOrderCPU,"Placing [tid:%i] on ready threads list\n", tid); readyThreads.push_back(tid); @@ -706,10 +708,20 @@ InOrderCPU::activateThread(ThreadID tid) "Adding [tid:%i] to active threads list.\n", tid); activeThreads.push_back(tid); + activateThreadInPipeline(tid); + wakeCPU(); } } +void +InOrderCPU::activateThreadInPipeline(ThreadID tid) +{ + for (int stNum=0; stNum < NumStages; stNum++) { + pipelineStage[stNum]->activateThread(tid); + } +} + void InOrderCPU::deactivateContext(ThreadID tid, int delay) { -- cgit v1.2.3 From 069b38c0d546708491d0da84668ba32f82ca7cb8 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:27:58 -0500 Subject: inorder: track last branch committed when threads are switching in/out the CPU, we need to keep track of special cases like branches. Add appropriate variables in ThreadState t track this and then use these variables when updating pc after context switch --- src/cpu/inorder/cpu.cc | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 501150386..8d41a18b4 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -709,7 +709,9 @@ InOrderCPU::activateThread(ThreadID tid) activeThreads.push_back(tid); activateThreadInPipeline(tid); - + + thread[tid]->lastActivate = curTick; + wakeCPU(); } } @@ -888,6 +890,7 @@ InOrderCPU::suspendThread(ThreadID tid) DPRINTF(InOrderCPU, "[tid: %i]: Placing on Suspended Threads List...\n", tid); deactivateThread(tid); suspendedThreads.push_back(tid); + thread[tid]->lastSuspend = curTick; } void @@ -1063,15 +1066,22 @@ void InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) { // Set the CPU's PCs - This contributes to the precise state of the CPU - // which can be used when restoring a thread to the CPU after a fork or - // after an exception - // ================= - // @TODO: Set-Up Grad-Info/Committed-Info to let ThreadState know if - // it's a branch or not + // which can be used when restoring a thread to the CPU after after any + // type of context switching activity (fork, exception, etc.) setPC(inst->readPC(), tid); setNextPC(inst->readNextPC(), tid); setNextNPC(inst->readNextNPC(), tid); + if (inst->isControl()) { + thread[tid]->lastGradIsBranch = true; + thread[tid]->lastBranchPC = inst->readPC(); + thread[tid]->lastBranchNextPC = inst->readNextPC(); + thread[tid]->lastBranchNextNPC = inst->readNextNPC(); + } else { + thread[tid]->lastGradIsBranch = false; + } + + // Finalize Trace Data For Instruction if (inst->traceData) { //inst->traceData->setCycle(curTick); @@ -1082,9 +1092,6 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) inst->traceData = NULL; } - // Set Last Graduated Instruction In Thread State - //thread[tid]->lastGradInst = inst; - // Increment thread-state's instruction count thread[tid]->numInst++; @@ -1108,7 +1115,7 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) // Broadcast to other resources an instruction // has been completed resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst, - tid); + 0, 0, tid); // Finally, remove instruction from CPU removeInst(inst); -- cgit v1.2.3 From 5e0b8337ed9c8aa975cd44df5565c2c3dde0c267 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:28:05 -0500 Subject: inorder: add/remove halt/deallocate context respectively Halt is called from the exit() system call while deallocate is unused. So to clear up things, just use halt and remove deallocate. --- src/cpu/inorder/cpu.cc | 65 ++++++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 8d41a18b4..5db86b258 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -98,7 +98,7 @@ std::string InOrderCPU::eventNames[NumCPUEvents] = "ActivateThread", "ActivateNextReadyThread", "DeactivateThread", - "DeallocateThread", + "HaltThread", "SuspendThread", "Trap", "InstGraduated", @@ -123,8 +123,8 @@ InOrderCPU::CPUEvent::process() cpu->deactivateThread(tid); break; - case DeallocateThread: - cpu->deallocateThread(tid); + case HaltThread: + cpu->haltThread(tid); break; case SuspendThread: @@ -140,8 +140,7 @@ InOrderCPU::CPUEvent::process() break; default: - fatal("Unrecognized Event Type %d", cpuEventType); - + fatal("Unrecognized Event Type %s", eventNames[cpuEventType]); } cpu->cpuEventRemoveList.push(this); @@ -759,40 +758,6 @@ InOrderCPU::deactivateThread(ThreadID tid) assert(!isThreadActive(tid)); } -void -InOrderCPU::deallocateContext(ThreadID tid, int delay) -{ - DPRINTF(InOrderCPU,"[tid:%i]: Deallocating ...\n", tid); - - scheduleCpuEvent(DeallocateThread, NoFault, tid, dummyInst, delay); - - // Be sure to signal that there's some activity so the CPU doesn't - // deschedule itself. - activityRec.activity(); - - _status = Running; -} - -void -InOrderCPU::deallocateThread(ThreadID tid) -{ - DPRINTF(InOrderCPU, "[tid:%i]: Calling deallocate thread.\n", tid); - - if (isThreadActive(tid)) { - DPRINTF(InOrderCPU,"[tid:%i]: Removing from active threads list\n", - tid); - list::iterator thread_it = - std::find(activeThreads.begin(), activeThreads.end(), tid); - - removePipelineStalls(*thread_it); - - activeThreads.erase(thread_it); - } - - // TODO: "Un"Load/Unmap register file state - -} - void InOrderCPU::removePipelineStalls(ThreadID tid) { @@ -874,20 +839,36 @@ InOrderCPU::activateNextReadyContext(int delay) void InOrderCPU::haltContext(ThreadID tid, int delay) { - suspendContext(tid, delay); + DPRINTF(InOrderCPU, "[tid:%i]: Calling Halt Context...\n", tid); + + scheduleCpuEvent(HaltThread, NoFault, tid, dummyInst, delay); + + activityRec.activity(); +} + +void +InOrderCPU::haltThread(ThreadID tid) +{ + DPRINTF(InOrderCPU, "[tid:%i]: Placing on Halted Threads List...\n", tid); + deactivateThread(tid); + squashThreadInPipeline(tid); + haltedThreads.push_back(tid); + + if (threadModel == SwitchOnCacheMiss) { + activateNextReadyContext(); + } } void InOrderCPU::suspendContext(ThreadID tid, int delay) { scheduleCpuEvent(SuspendThread, NoFault, tid, dummyInst, delay); - //_status = Idle; } void InOrderCPU::suspendThread(ThreadID tid) { - DPRINTF(InOrderCPU, "[tid: %i]: Placing on Suspended Threads List...\n", tid); + DPRINTF(InOrderCPU, "[tid:%i]: Placing on Suspended Threads List...\n", tid); deactivateThread(tid); suspendedThreads.push_back(tid); thread[tid]->lastSuspend = curTick; -- cgit v1.2.3 From b4e0ef78379dd5bab0ee6ec824bca3f51dd484c6 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:28:12 -0500 Subject: inorder: set thread status' set Active/Suspended/Halted status for threads. useful for system when determining if/when to exit simulation --- src/cpu/inorder/cpu.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 5db86b258..d8fea79d9 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -711,6 +711,8 @@ InOrderCPU::activateThread(ThreadID tid) thread[tid]->lastActivate = curTick; + tcBase(tid)->setStatus(ThreadContext::Active); + wakeCPU(); } } @@ -750,9 +752,11 @@ InOrderCPU::deactivateThread(ThreadID tid) removePipelineStalls(*thread_it); - //@TODO: change stage status' to Idle? - activeThreads.erase(thread_it); + + // Ideally, this should be triggered from the + // suspendContext/Thread functions + tcBase(tid)->setStatus(ThreadContext::Suspended); } assert(!isThreadActive(tid)); @@ -854,6 +858,8 @@ InOrderCPU::haltThread(ThreadID tid) squashThreadInPipeline(tid); haltedThreads.push_back(tid); + tcBase(tid)->setStatus(ThreadContext::Halted); + if (threadModel == SwitchOnCacheMiss) { activateNextReadyContext(); } @@ -872,6 +878,8 @@ InOrderCPU::suspendThread(ThreadID tid) deactivateThread(tid); suspendedThreads.push_back(tid); thread[tid]->lastSuspend = curTick; + + tcBase(tid)->setStatus(ThreadContext::Suspended); } void -- cgit v1.2.3 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 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') 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); } -- cgit v1.2.3 From 0b29c2d057d2d6f4f8b9b7853da91bcb283e805c Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:28:59 -0500 Subject: inorder: ctxt switch stats - m5 line enforcement on use_def.cc,hh --- src/cpu/inorder/cpu.cc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 4cc9b9f22..b69fe2e3b 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -189,7 +189,8 @@ InOrderCPU::InOrderCPU(Params *params) #endif // DEBUG switchCount(0), deferRegistration(false/*params->deferRegistration*/), - stageTracing(params->stageTracing) + stageTracing(params->stageTracing), + instsPerSwitch(0) { ThreadID active_threads; cpu_params = params; @@ -352,6 +353,15 @@ InOrderCPU::regStats() } /* Register any of the InOrderCPU's stats here.*/ + instsPerCtxtSwitch + .name(name() + ".instsPerContextSwitch") + .desc("Instructions Committed Per Context Switch") + .prereq(instsPerCtxtSwitch); + + numCtxtSwitches + .name(name() + ".contextSwitches") + .desc("Number of context switches"); + timesIdled .name(name() + ".timesIdled") .desc("Number of times that the entire CPU went into an idle state and" @@ -719,6 +729,8 @@ InOrderCPU::activateThread(ThreadID tid) tcBase(tid)->setStatus(ThreadContext::Active); wakeCPU(); + + numCtxtSwitches++; } } @@ -1056,6 +1068,15 @@ InOrderCPU::addInst(DynInstPtr &inst) return --(instList[tid].end()); } +void +InOrderCPU::updateContextSwitchStats() +{ + // Set Average Stat Here, then reset to 0 + instsPerCtxtSwitch = instsPerSwitch; + instsPerSwitch = 0; +} + + void InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) { @@ -1086,6 +1107,9 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) inst->traceData = NULL; } + // Increment active thread's instruction count + instsPerSwitch++; + // Increment thread-state's instruction count thread[tid]->numInst++; -- cgit v1.2.3 From 1a89e8f4cbab3b3a6fd144d3d08dfeaac203f945 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:29:59 -0500 Subject: inorder: user per-thread dummy insts/reqs --- src/cpu/inorder/cpu.cc | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index b69fe2e3b..472317362 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -211,6 +211,7 @@ InOrderCPU::InOrderCPU(Params *params) "edit your workload size."); } + if (active_threads > 1) { threadModel = (InOrderCPU::ThreadModel) params->threadModel; @@ -257,6 +258,9 @@ InOrderCPU::InOrderCPU(Params *params) Process* dummy_proc = params->workload[0]; thread[tid] = new Thread(this, tid, dummy_proc); } + + // Eventually set this with parameters... + asid[tid] = tid; #endif // Setup the TC that will serve as the interface to the threads/CPU. @@ -313,14 +317,24 @@ InOrderCPU::InOrderCPU(Params *params) isa[tid].clear(); isa[tid].expandForMultithreading(numThreads, 1/*numVirtProcs*/); + + // Define dummy instructions and resource requests to be used. + dummyInst[tid] = new InOrderDynInst(this, + thread[tid], + 0, + tid, + asid[tid]); + + dummyReq[tid] = new ResourceRequest(resPool->getResource(0), + dummyInst[tid], + 0, + 0, + 0, + 0); } lastRunningCycle = curTick; - // Define dummy instructions and resource requests to be used. - dummyInst = new InOrderDynInst(this, NULL, 0, 0); - dummyReq = new ResourceRequest(resPool->getResource(0), NULL, 0, 0, 0, 0); - // Reset CPU to reset state. #if FULL_SYSTEM Fault resetFault = new ResetFault(); @@ -585,7 +599,7 @@ void InOrderCPU::trap(Fault fault, ThreadID tid, int delay) { //@ Squash Pipeline during TRAP - scheduleCpuEvent(Trap, fault, tid, dummyInst, delay); + scheduleCpuEvent(Trap, fault, tid, dummyInst[tid], delay); } void @@ -747,7 +761,7 @@ InOrderCPU::deactivateContext(ThreadID tid, int delay) { DPRINTF(InOrderCPU,"[tid:%i]: Deactivating ...\n", tid); - scheduleCpuEvent(DeactivateThread, NoFault, tid, dummyInst, delay); + scheduleCpuEvent(DeactivateThread, NoFault, tid, dummyInst[tid], delay); // Be sure to signal that there's some activity so the CPU doesn't // deschedule itself. @@ -830,7 +844,8 @@ InOrderCPU::activateContext(ThreadID tid, int delay) { DPRINTF(InOrderCPU,"[tid:%i]: Activating ...\n", tid); - scheduleCpuEvent(ActivateThread, NoFault, tid, dummyInst, delay); + + scheduleCpuEvent(ActivateThread, NoFault, tid, dummyInst[tid], delay); // Be sure to signal that there's some activity so the CPU doesn't // deschedule itself. @@ -847,7 +862,7 @@ InOrderCPU::activateNextReadyContext(int delay) // 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, + scheduleCpuEvent(ActivateNextReadyThread, NoFault, 0/*tid*/, dummyInst[0], delay, 5); // Be sure to signal that there's some activity so the CPU doesn't @@ -862,7 +877,7 @@ InOrderCPU::haltContext(ThreadID tid, int delay) { DPRINTF(InOrderCPU, "[tid:%i]: Calling Halt Context...\n", tid); - scheduleCpuEvent(HaltThread, NoFault, tid, dummyInst, delay); + scheduleCpuEvent(HaltThread, NoFault, tid, dummyInst[tid], delay); activityRec.activity(); } @@ -885,7 +900,7 @@ InOrderCPU::haltThread(ThreadID tid) void InOrderCPU::suspendContext(ThreadID tid, int delay) { - scheduleCpuEvent(SuspendThread, NoFault, tid, dummyInst, delay); + scheduleCpuEvent(SuspendThread, NoFault, tid, dummyInst[tid], delay); } void -- cgit v1.2.3 From f3bc2df663cccd7db7a4ba87acfc2d0137a5ca02 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:30:08 -0500 Subject: inorder: object cleanup in destructors --- src/cpu/inorder/cpu.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 472317362..a3b203559 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -347,6 +347,11 @@ InOrderCPU::InOrderCPU(Params *params) scheduleTickEvent(0); } +InOrderCPU::~InOrderCPU() +{ + delete resPool; +} + void InOrderCPU::regStats() -- cgit v1.2.3 From ea8909925fd0e7a33feabc9e17f83b85cd7c6039 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:30:24 -0500 Subject: inorder: add activity stats --- src/cpu/inorder/cpu.cc | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index a3b203559..e864c8c86 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -389,9 +389,17 @@ InOrderCPU::regStats() idleCycles .name(name() + ".idleCycles") - .desc("Total number of cycles that the CPU has spent unscheduled due " - "to idling") - .prereq(idleCycles); + .desc("Number of cycles cpu's stages were not processed"); + + runCycles + .name(name() + ".runCycles") + .desc("Number of cycles cpu stages are processed."); + + activity + .name(name() + ".activity") + .desc("Percentage of cycles cpu is active") + .precision(6); + activity = (runCycles / numCycles) * 100; threadCycles .init(numThreads) @@ -463,18 +471,27 @@ InOrderCPU::tick() ++numCycles; + bool pipes_idle = true; + //Tick each of the stages for (int stNum=NumStages - 1; stNum >= 0 ; stNum--) { pipelineStage[stNum]->tick(); + + pipes_idle = pipes_idle && pipelineStage[stNum]->idle; } + if (pipes_idle) + idleCycles++; + else + runCycles++; + // Now advance the time buffers one tick timeBuffer.advance(); for (int sqNum=0; sqNum < NumStages - 1; sqNum++) { stageQueue[sqNum]->advance(); } activityRec.advance(); - + // Any squashed requests, events, or insts then remove them now cleanUpRemovedReqs(); cleanUpRemovedEvents(); -- cgit v1.2.3 From 9357e353fc976a409fb0cb3a875b402f452577f7 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:30:48 -0500 Subject: inorder: inst count mgmt --- src/cpu/inorder/cpu.cc | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index e864c8c86..e28af9e7a 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -333,6 +333,12 @@ InOrderCPU::InOrderCPU(Params *params) 0); } + dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0); + dummyReqInst->setSquashed(); + + dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0, 0); + dummyBufferInst->setSquashed(); + lastRunningCycle = curTick; // Reset CPU to reset state. @@ -343,6 +349,8 @@ InOrderCPU::InOrderCPU(Params *params) reset(); #endif + dummyBufferInst->resetInstCount(); + // Schedule First Tick Event, CPU will reschedule itself from here on out. scheduleTickEvent(0); } @@ -1176,6 +1184,8 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) removeInst(inst); } +// currently unused function, but substitute repetitive code w/this function +// call void InOrderCPU::addToRemoveList(DynInstPtr &inst) { @@ -1194,6 +1204,10 @@ InOrderCPU::removeInst(DynInstPtr &inst) removeInstsThisCycle = true; // Remove the instruction. + + DPRINTF(RefCount, "Pushing instruction [tid:%i] PC %#x " + "[sn:%lli] to remove list\n", + inst->threadNumber, inst->readPC(), inst->seqNum); removeList.push(inst->getInstListIt()); } @@ -1208,7 +1222,7 @@ InOrderCPU::removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid) inst_iter--; - DPRINTF(InOrderCPU, "Deleting instructions from CPU instruction " + DPRINTF(InOrderCPU, "Squashing instructions from CPU instruction " "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n", tid, seq_num, (*inst_iter)->seqNum); @@ -1238,6 +1252,9 @@ InOrderCPU::squashInstIt(const ListIt &instIt, ThreadID tid) (*instIt)->setSquashed(); + DPRINTF(RefCount, "Pushing instruction [tid:%i] PC %#x " + "[sn:%lli] to remove list\n", + (*instIt)->threadNumber, (*instIt)->readPC(), (*instIt)->seqNum); removeList.push(instIt); } } @@ -1251,7 +1268,7 @@ InOrderCPU::cleanUpRemovedInsts() "[tid:%i] [sn:%lli] PC %#x\n", (*removeList.front())->threadNumber, (*removeList.front())->seqNum, - (*removeList.front())->readPC()); + (*removeList.front())->readPC()); DynInstPtr inst = *removeList.front(); ThreadID tid = inst->threadNumber; @@ -1279,11 +1296,6 @@ InOrderCPU::cleanUpRemovedInsts() instList[tid].erase(removeList.front()); removeList.pop(); - - DPRINTF(RefCount, "pop from remove list: [sn:%i]: Refcount = %i.\n", - inst->seqNum, - 0/*inst->curCount()*/); - } removeInstsThisCycle = false; @@ -1295,22 +1307,18 @@ InOrderCPU::cleanUpRemovedReqs() while (!reqRemoveList.empty()) { ResourceRequest *res_req = reqRemoveList.front(); - DPRINTF(RefCount, "[tid:%i]: Removing Request, " - "[sn:%lli] [slot:%i] [stage_num:%i] [res:%s] [refcount:%i].\n", + DPRINTF(InOrderCPU, "[tid:%i] [sn:%lli]: Removing Request " + "[stage_num:%i] [res:%s] [slot:%i] [completed:%i].\n", res_req->inst->threadNumber, res_req->inst->seqNum, - res_req->getSlot(), res_req->getStageNum(), res_req->res->name(), - 0/*res_req->inst->curCount()*/); + (res_req->isCompleted()) ? res_req->getComplSlot() : res_req->getSlot(), + res_req->isCompleted()); reqRemoveList.pop(); delete res_req; - - DPRINTF(RefCount, "after remove request: [sn:%i]: Refcount = %i.\n", - res_req->inst->seqNum, - 0/*res_req->inst->curCount()*/); } } -- cgit v1.2.3 From c7f6e2661c958d996479ae9fe8c8cf2c8a9482f6 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:30:59 -0500 Subject: inorder: double delete inst bug Make sure that instructions are dereferenced/deleted twice by marking they are on the remove list --- src/cpu/inorder/cpu.cc | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'src/cpu/inorder/cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index e28af9e7a..7342f9bc5 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -1190,8 +1190,18 @@ void InOrderCPU::addToRemoveList(DynInstPtr &inst) { removeInstsThisCycle = true; - - removeList.push(inst->getInstListIt()); + if (!inst->isRemoveList()) { + DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %#x " + "[sn:%lli] to remove list\n", + inst->threadNumber, inst->readPC(), inst->seqNum); + inst->setRemoveList(); + removeList.push(inst->getInstListIt()); + } else { + DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %#x " + "[sn:%lli], already remove list\n", + inst->threadNumber, inst->readPC(), inst->seqNum); + } + } void @@ -1204,11 +1214,18 @@ InOrderCPU::removeInst(DynInstPtr &inst) removeInstsThisCycle = true; // Remove the instruction. + if (!inst->isRemoveList()) { + DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %#x " + "[sn:%lli] to remove list\n", + inst->threadNumber, inst->readPC(), inst->seqNum); + inst->setRemoveList(); + removeList.push(inst->getInstListIt()); + } else { + DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %#x " + "[sn:%lli], already on remove list\n", + inst->threadNumber, inst->readPC(), inst->seqNum); + } - DPRINTF(RefCount, "Pushing instruction [tid:%i] PC %#x " - "[sn:%lli] to remove list\n", - inst->threadNumber, inst->readPC(), inst->seqNum); - removeList.push(inst->getInstListIt()); } void @@ -1252,11 +1269,22 @@ InOrderCPU::squashInstIt(const ListIt &instIt, ThreadID tid) (*instIt)->setSquashed(); - DPRINTF(RefCount, "Pushing instruction [tid:%i] PC %#x " - "[sn:%lli] to remove list\n", - (*instIt)->threadNumber, (*instIt)->readPC(), (*instIt)->seqNum); - removeList.push(instIt); + if (!(*instIt)->isRemoveList()) { + DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %#x " + "[sn:%lli] to remove list\n", + (*instIt)->threadNumber, (*instIt)->readPC(), + (*instIt)->seqNum); + (*instIt)->setRemoveList(); + removeList.push(instIt); + } else { + DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %#x " + "[sn:%lli], already on remove list\n", + (*instIt)->threadNumber, (*instIt)->readPC(), + (*instIt)->seqNum); + } + } + } -- cgit v1.2.3