From 4dbc2f17180d3d8c82d5414daa55b102de9755e5 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:27:02 -0500 Subject: [PATCH] inorder: suspend in respool give resources their own specific activity to do for a "suspend" event instead of defaulting to deactivating the thread for a suspend thread event. This really matters for the fetch sequence unit which wants to remove the thread from fetching while other units want to ignore a thread suspension. If you deactivate a thread in a resource then you may lose some of the allotted bandwidth that the thread is taking up... --- src/cpu/inorder/resource.hh | 4 ++ src/cpu/inorder/resource_pool.cc | 48 ++++++++++++++++++--- src/cpu/inorder/resource_pool.hh | 3 ++ src/cpu/inorder/resources/cache_unit.cc | 14 +++++- src/cpu/inorder/resources/fetch_seq_unit.cc | 6 +++ src/cpu/inorder/resources/fetch_seq_unit.hh | 1 + 6 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh index f7c4b8fcd..4ae4db818 100644 --- a/src/cpu/inorder/resource.hh +++ b/src/cpu/inorder/resource.hh @@ -93,6 +93,10 @@ class Resource { */ virtual void deactivateThread(ThreadID tid); + /** Resources that care about thread activation override this. */ + virtual void suspendThread(ThreadID tid) { } + + /** Resources that care when an instruction has been graduated * can override this */ diff --git a/src/cpu/inorder/resource_pool.cc b/src/cpu/inorder/resource_pool.cc index 97ba4d087..45a4a9e60 100644 --- a/src/cpu/inorder/resource_pool.cc +++ b/src/cpu/inorder/resource_pool.cc @@ -226,7 +226,7 @@ ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst, } break; - case InOrderCPU::SuspendThread: + case InOrderCPU::DeactivateThread: case InOrderCPU::DeallocateThread: { @@ -246,6 +246,23 @@ ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst, } break; + case InOrderCPU::SuspendThread: + { + + DPRINTF(Resource, "Scheduling Suspend Thread Resource Pool Event for tick %i.\n", + curTick + delay); + ResPoolEvent *res_pool_event = new ResPoolEvent(this, + e_type, + inst, + inst->squashingStage, + inst->bdelaySeqNum, + tid); + + mainEventQueue.schedule(res_pool_event, curTick + cpu->ticks(delay)); + + } + break; + case ResourcePool::InstGraduated: { DPRINTF(Resource, "Scheduling Inst-Graduated Resource Pool " @@ -309,8 +326,9 @@ void ResourcePool::squashAll(DynInstPtr inst, int stage_num, InstSeqNum done_seq_num, ThreadID tid) { - DPRINTF(Resource, "[tid:%i] Stage %i squashing all instructions above " - "[sn:%i].\n", tid, stage_num, done_seq_num); + DPRINTF(Resource, "[tid:%i] Broadcasting Squash All Event " + " starting w/stage %i for all instructions above [sn:%i].\n", + tid, stage_num, done_seq_num); int num_resources = resources.size(); @@ -323,8 +341,9 @@ void ResourcePool::squashDueToMemStall(DynInstPtr inst, int stage_num, 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); + DPRINTF(Resource, "[tid:%i] Broadcasting SquashDueToMemStall Event" + " starting w/stage %i for all instructions above [sn:%i].\n", + tid, stage_num, done_seq_num); int num_resources = resources.size(); @@ -370,6 +389,19 @@ ResourcePool::deactivateAll(ThreadID tid) } } +void +ResourcePool::suspendAll(ThreadID tid) +{ + DPRINTF(Resource, "[tid:%i] Broadcasting Thread Suspension to all resources.\n", + tid); + + int num_resources = resources.size(); + + for (int idx = 0; idx < num_resources; idx++) { + resources[idx]->suspendThread(tid); + } +} + void ResourcePool::instGraduated(InstSeqNum seq_num, ThreadID tid) { @@ -409,11 +441,15 @@ ResourcePool::ResPoolEvent::process() resPool->activateAll(tid); break; - case InOrderCPU::SuspendThread: + case InOrderCPU::DeactivateThread: case InOrderCPU::DeallocateThread: resPool->deactivateAll(tid); break; + case InOrderCPU::SuspendThread: + resPool->suspendAll(tid); + break; + case ResourcePool::InstGraduated: resPool->instGraduated(seqNum, tid); break; diff --git a/src/cpu/inorder/resource_pool.hh b/src/cpu/inorder/resource_pool.hh index 61e691f35..ae63c4c59 100644 --- a/src/cpu/inorder/resource_pool.hh +++ b/src/cpu/inorder/resource_pool.hh @@ -172,6 +172,9 @@ class ResourcePool { /** De-Activate Thread in all resources */ void deactivateAll(ThreadID tid); + /** De-Activate Thread in all resources */ + void suspendAll(ThreadID tid); + /** Broadcast graduation to all resources */ void instGraduated(InstSeqNum seq_num, ThreadID tid); diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 570d27fbe..8f92db3e4 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -158,9 +158,9 @@ CacheUnit::getSlot(DynInstPtr inst) return new_slot; } else { DPRINTF(InOrderCachePort, - "Denying request because there is an outstanding" + "[tid:%i] Denying request because there is an outstanding" " request to/for addr. %08p. by [sn:%i] @ tick %i\n", - req_addr, addrMap[req_addr], inst->memTime); + inst->readTid(), req_addr, addrMap[req_addr], inst->memTime); return -1; } } @@ -702,6 +702,13 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) cache_req->setMemAccPending(false); cache_req->setMemAccCompleted(); + if (cache_req->isMemStall() && + cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) { + DPRINTF(InOrderCachePort, "[tid:%u] Waking up from Cache Miss.\n"); + + cpu->activateContext(tid); + } + // Wake up the CPU (if it went to sleep and was waiting on this // completion event). cpu->wakeCPU(); @@ -784,6 +791,9 @@ CacheUnit::squashDueToMemStall(DynInstPtr inst, int stage_num, // thread then you need to reevaluate this code // NOTE: squash should originate from // pipeline_stage.cc:processInstSchedule + DPRINTF(InOrderCachePort, "Squashing above [sn:%u]\n", + squash_seq_num + 1); + squash(inst, stage_num, squash_seq_num + 1, tid); } diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index 1d0b92075..e0b9ea1f9 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -336,3 +336,9 @@ FetchSeqUnit::deactivateThread(ThreadID tid) if (thread_it != cpu->fetchPriorityList.end()) cpu->fetchPriorityList.erase(thread_it); } + +void +FetchSeqUnit::suspendThread(ThreadID tid) +{ + deactivateThread(tid); +} diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh index a4495564b..fdbc4521f 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.hh +++ b/src/cpu/inorder/resources/fetch_seq_unit.hh @@ -59,6 +59,7 @@ class FetchSeqUnit : public Resource { virtual void init(); virtual void activateThread(ThreadID tid); virtual void deactivateThread(ThreadID tid); + virtual void suspendThread(ThreadID tid); virtual void execute(int slot_num); /** Override default Resource squash sequence. This actually,