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...
This commit is contained in:
Korey Sewell 2010-01-31 18:27:02 -05:00
parent 4ea296e296
commit 4dbc2f1718
6 changed files with 68 additions and 8 deletions

View file

@ -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
*/

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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,