Support for draining, and the new method of switching out. Now switching out happens after the pipeline has been drained, deferring the three way handshake to the normal drain mechanism. The calls of switchOut() and takeOverFrom() both take action immediately.

src/cpu/o3/commit.hh:
src/cpu/o3/commit_impl.hh:
src/cpu/o3/cpu.cc:
src/cpu/o3/cpu.hh:
src/cpu/o3/decode.hh:
src/cpu/o3/decode_impl.hh:
src/cpu/o3/fetch.hh:
src/cpu/o3/fetch_impl.hh:
src/cpu/o3/iew.hh:
src/cpu/o3/iew_impl.hh:
src/cpu/o3/rename.hh:
src/cpu/o3/rename_impl.hh:
    Support for draining, new method of switching out.

--HG--
extra : convert_revision : 05bf8b271ec85b3e2c675c3bed6c42aeba21f465
This commit is contained in:
Kevin Lim 2006-07-06 13:59:02 -04:00
parent 8c547d80b1
commit 30c516d51c
12 changed files with 154 additions and 70 deletions

View file

@ -187,11 +187,14 @@ class DefaultCommit
/** Initializes stage by sending back the number of free entries. */ /** Initializes stage by sending back the number of free entries. */
void initStage(); void initStage();
/** Initializes the switching out of commit. */ /** Initializes the draining of commit. */
void switchOut(); void drain();
/** Resumes execution after draining. */
void resume();
/** Completes the switch out of commit. */ /** Completes the switch out of commit. */
void doSwitchOut(); void switchOut();
/** Takes over from another CPU's thread. */ /** Takes over from another CPU's thread. */
void takeOverFrom(); void takeOverFrom();
@ -383,8 +386,8 @@ class DefaultCommit
/** Number of Active Threads */ /** Number of Active Threads */
unsigned numThreads; unsigned numThreads;
/** Is a switch out pending. */ /** Is a drain pending. */
bool switchPending; bool drainPending;
/** Is commit switched out. */ /** Is commit switched out. */
bool switchedOut; bool switchedOut;

View file

@ -80,7 +80,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
renameWidth(params->renameWidth), renameWidth(params->renameWidth),
commitWidth(params->commitWidth), commitWidth(params->commitWidth),
numThreads(params->numberOfThreads), numThreads(params->numberOfThreads),
switchPending(false), drainPending(false),
switchedOut(false), switchedOut(false),
trapLatency(params->trapLatency), trapLatency(params->trapLatency),
fetchTrapLatency(params->fetchTrapLatency) fetchTrapLatency(params->fetchTrapLatency)
@ -351,20 +351,26 @@ DefaultCommit<Impl>::initStage()
template <class Impl> template <class Impl>
void void
DefaultCommit<Impl>::switchOut() DefaultCommit<Impl>::drain()
{ {
switchPending = true; drainPending = true;
} }
template <class Impl> template <class Impl>
void void
DefaultCommit<Impl>::doSwitchOut() DefaultCommit<Impl>::switchOut()
{ {
switchedOut = true; switchedOut = true;
switchPending = false; drainPending = false;
rob->switchOut(); rob->switchOut();
} }
template <class Impl>
void
DefaultCommit<Impl>::resume()
{
}
template <class Impl> template <class Impl>
void void
DefaultCommit<Impl>::takeOverFrom() DefaultCommit<Impl>::takeOverFrom()
@ -557,8 +563,9 @@ DefaultCommit<Impl>::tick()
wroteToTimeBuffer = false; wroteToTimeBuffer = false;
_nextStatus = Inactive; _nextStatus = Inactive;
if (switchPending && rob->isEmpty() && !iewStage->hasStoresToWB()) { if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
cpu->signalSwitched(); cpu->signalDrained();
drainPending = false;
return; return;
} }

View file

@ -158,7 +158,7 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
physmem(system->physmem), physmem(system->physmem),
#endif // FULL_SYSTEM #endif // FULL_SYSTEM
mem(params->mem), mem(params->mem),
switchCount(0), drainCount(0),
deferRegistration(params->deferRegistration), deferRegistration(params->deferRegistration),
numThreads(number_of_threads) numThreads(number_of_threads)
{ {
@ -713,45 +713,72 @@ FullO3CPU<Impl>::haltContext(int tid)
} }
template <class Impl> template <class Impl>
void bool
FullO3CPU<Impl>::switchOut() FullO3CPU<Impl>::drain(Event *drain_event)
{ {
switchCount = 0; drainCount = 0;
fetch.switchOut(); drainEvent = drain_event;
decode.switchOut(); fetch.drain();
rename.switchOut(); decode.drain();
iew.switchOut(); rename.drain();
commit.switchOut(); iew.drain();
commit.drain();
// Wake the CPU and record activity so everything can drain out if // Wake the CPU and record activity so everything can drain out if
// the CPU is currently idle. // the CPU is currently idle.
wakeCPU(); wakeCPU();
activityRec.activity(); activityRec.activity();
return false;
} }
template <class Impl> template <class Impl>
void void
FullO3CPU<Impl>::signalSwitched() FullO3CPU<Impl>::resume()
{ {
if (++switchCount == NumStages) { if (_status == SwitchedOut)
fetch.doSwitchOut(); return;
rename.doSwitchOut(); fetch.resume();
commit.doSwitchOut(); decode.resume();
instList.clear(); rename.resume();
while (!removeList.empty()) { iew.resume();
removeList.pop(); commit.resume();
}
#if USE_CHECKER if (!tickEvent.scheduled())
if (checker) tickEvent.schedule(curTick);
checker->switchOut(); _status = Running;
#endif }
template <class Impl>
void
FullO3CPU<Impl>::signalDrained()
{
if (++drainCount == NumStages) {
if (tickEvent.scheduled()) if (tickEvent.scheduled())
tickEvent.squash(); tickEvent.squash();
_status = SwitchedOut; _status = Drained;
drainEvent->process();
} }
assert(switchCount <= 5); assert(drainCount <= 5);
}
template <class Impl>
void
FullO3CPU<Impl>::switchOut()
{
fetch.switchOut();
rename.switchOut();
commit.switchOut();
instList.clear();
while (!removeList.empty()) {
removeList.pop();
}
_status = SwitchedOut;
#if USE_CHECKER
if (checker)
checker->switchOut();
#endif
} }
template <class Impl> template <class Impl>

View file

@ -57,6 +57,8 @@ class Checker;
class ThreadContext; class ThreadContext;
template <class> template <class>
class O3ThreadContext; class O3ThreadContext;
class Checkpoint;
class MemObject; class MemObject;
class Process; class Process;
@ -109,6 +111,7 @@ class FullO3CPU : public BaseO3CPU
Idle, Idle,
Halted, Halted,
Blocked, Blocked,
Drained,
SwitchedOut SwitchedOut
}; };
@ -270,14 +273,21 @@ class FullO3CPU : public BaseO3CPU
*/ */
virtual void syscall(int tid) { panic("Unimplemented!"); } virtual void syscall(int tid) { panic("Unimplemented!"); }
/** Switches out this CPU. */ /** Starts draining the CPU's pipeline of all instructions in
void switchOut(); * order to stop all memory accesses. */
virtual bool drain(Event *drain_event);
/** Resumes execution after a drain. */
virtual void resume();
/** Signals to this CPU that a stage has completed switching out. */ /** Signals to this CPU that a stage has completed switching out. */
void signalSwitched(); void signalDrained();
/** Switches out this CPU. */
virtual void switchOut();
/** Takes over from another CPU. */ /** Takes over from another CPU. */
void takeOverFrom(BaseCPU *oldCPU); virtual void takeOverFrom(BaseCPU *oldCPU);
/** Get the current instruction sequence number, and increment it. */ /** Get the current instruction sequence number, and increment it. */
InstSeqNum getAndIncrementInstSeq() InstSeqNum getAndIncrementInstSeq()
@ -550,8 +560,11 @@ class FullO3CPU : public BaseO3CPU
/** Pointer to memory. */ /** Pointer to memory. */
MemObject *mem; MemObject *mem;
/** Counter of how many stages have completed switching out. */ /** Event to call process() on once draining has completed. */
int switchCount; Event *drainEvent;
/** Counter of how many stages have completed draining. */
int drainCount;
/** Pointers to all of the threads in the CPU. */ /** Pointers to all of the threads in the CPU. */
std::vector<Thread *> thread; std::vector<Thread *> thread;

View file

@ -109,8 +109,14 @@ class DefaultDecode
/** Sets pointer to list of active threads. */ /** Sets pointer to list of active threads. */
void setActiveThreads(std::list<unsigned> *at_ptr); void setActiveThreads(std::list<unsigned> *at_ptr);
/** Drains the decode stage. */
void drain();
/** Resumes execution after a drain. */
void resume() { }
/** Switches out the decode stage. */ /** Switches out the decode stage. */
void switchOut(); void switchOut() { }
/** Takes over from another CPU's thread. */ /** Takes over from another CPU's thread. */
void takeOverFrom(); void takeOverFrom();

View file

@ -166,10 +166,10 @@ DefaultDecode<Impl>::setActiveThreads(list<unsigned> *at_ptr)
template <class Impl> template <class Impl>
void void
DefaultDecode<Impl>::switchOut() DefaultDecode<Impl>::drain()
{ {
// Decode can immediately switch out. // Decode is done draining at any time.
cpu->signalSwitched(); cpu->signalDrained();
} }
template <class Impl> template <class Impl>

View file

@ -180,11 +180,14 @@ class DefaultFetch
/** Processes cache completion event. */ /** Processes cache completion event. */
void processCacheCompletion(PacketPtr pkt); void processCacheCompletion(PacketPtr pkt);
/** Begins the switch out of the fetch stage. */ /** Begins the drain of the fetch stage. */
void switchOut(); void drain();
/** Completes the switch out of the fetch stage. */ /** Resumes execution after a drain. */
void doSwitchOut(); void resume();
/** Tells fetch stage to prepare to be switched out. */
void switchOut();
/** Takes over from another CPU's thread. */ /** Takes over from another CPU's thread. */
void takeOverFrom(); void takeOverFrom();
@ -421,6 +424,9 @@ class DefaultFetch
*/ */
bool interruptPending; bool interruptPending;
/** Is there a drain pending. */
bool drainPending;
/** Records if fetch is switched out. */ /** Records if fetch is switched out. */
bool switchedOut; bool switchedOut;

View file

@ -109,6 +109,7 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
numThreads(params->numberOfThreads), numThreads(params->numberOfThreads),
numFetchingThreads(params->smtNumFetchingThreads), numFetchingThreads(params->smtNumFetchingThreads),
interruptPending(false), interruptPending(false),
drainPending(false),
switchedOut(false) switchedOut(false)
{ {
if (numThreads > Impl::MaxThreads) if (numThreads > Impl::MaxThreads)
@ -353,7 +354,8 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
// to return. // to return.
if (fetchStatus[tid] != IcacheWaitResponse || if (fetchStatus[tid] != IcacheWaitResponse ||
pkt->req != memReq[tid] || pkt->req != memReq[tid] ||
isSwitchedOut()) { isSwitchedOut() ||
drainPending) {
++fetchIcacheSquashes; ++fetchIcacheSquashes;
delete pkt->req; delete pkt->req;
delete pkt; delete pkt;
@ -384,17 +386,25 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
template <class Impl> template <class Impl>
void void
DefaultFetch<Impl>::switchOut() DefaultFetch<Impl>::drain()
{ {
// Fetch is ready to switch out at any time. // Fetch is ready to drain at any time.
switchedOut = true; cpu->signalDrained();
cpu->signalSwitched(); drainPending = true;
} }
template <class Impl> template <class Impl>
void void
DefaultFetch<Impl>::doSwitchOut() DefaultFetch<Impl>::resume()
{ {
drainPending = false;
}
template <class Impl>
void
DefaultFetch<Impl>::switchOut()
{
switchedOut = true;
// Branch predictor needs to have its state cleared. // Branch predictor needs to have its state cleared.
branchPred.switchOut(); branchPred.switchOut();
} }
@ -498,7 +508,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
unsigned flags = 0; unsigned flags = 0;
#endif // FULL_SYSTEM #endif // FULL_SYSTEM
if (cacheBlocked || (interruptPending && flags == 0) || switchedOut) { if (cacheBlocked || (interruptPending && flags == 0) || drainPending) {
// Hold off fetch from getting new instructions when: // Hold off fetch from getting new instructions when:
// Cache is blocked, or // Cache is blocked, or
// while an interrupt is pending and we're not in PAL mode, or // while an interrupt is pending and we're not in PAL mode, or

View file

@ -143,11 +143,14 @@ class DefaultIEW
/** Sets pointer to the scoreboard. */ /** Sets pointer to the scoreboard. */
void setScoreboard(Scoreboard *sb_ptr); void setScoreboard(Scoreboard *sb_ptr);
/** Starts switch out of IEW stage. */ /** Drains IEW stage. */
void switchOut(); void drain();
/** Resumes execution after a drain. */
void resume();
/** Completes switch out of IEW stage. */ /** Completes switch out of IEW stage. */
void doSwitchOut(); void switchOut();
/** Takes over from another CPU's thread. */ /** Takes over from another CPU's thread. */
void takeOverFrom(); void takeOverFrom();

View file

@ -355,15 +355,21 @@ DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
template <class Impl> template <class Impl>
void void
DefaultIEW<Impl>::switchOut() DefaultIEW<Impl>::drain()
{ {
// IEW is ready to switch out at any time. // IEW is ready to drain at any time.
cpu->signalSwitched(); cpu->signalDrained();
} }
template <class Impl> template <class Impl>
void void
DefaultIEW<Impl>::doSwitchOut() DefaultIEW<Impl>::resume()
{
}
template <class Impl>
void
DefaultIEW<Impl>::switchOut()
{ {
// Clear any state. // Clear any state.
switchedOut = true; switchedOut = true;

View file

@ -157,12 +157,15 @@ class DefaultRename
/** Sets pointer to the scoreboard. */ /** Sets pointer to the scoreboard. */
void setScoreboard(Scoreboard *_scoreboard); void setScoreboard(Scoreboard *_scoreboard);
/** Drains the rename stage. */
void drain();
/** Resumes execution after a drain. */
void resume() { }
/** Switches out the rename stage. */ /** Switches out the rename stage. */
void switchOut(); void switchOut();
/** Completes the switch out. */
void doSwitchOut();
/** Takes over from another CPU's thread. */ /** Takes over from another CPU's thread. */
void takeOverFrom(); void takeOverFrom();

View file

@ -258,15 +258,15 @@ DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
template <class Impl> template <class Impl>
void void
DefaultRename<Impl>::switchOut() DefaultRename<Impl>::drain()
{ {
// Rename is ready to switch out at any time. // Rename is ready to switch out at any time.
cpu->signalSwitched(); cpu->signalDrained();
} }
template <class Impl> template <class Impl>
void void
DefaultRename<Impl>::doSwitchOut() DefaultRename<Impl>::switchOut()
{ {
// Clear any state, fix up the rename map. // Clear any state, fix up the rename map.
for (int i = 0; i < numThreads; i++) { for (int i = 0; i < numThreads; i++) {