summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2012-08-28 14:30:31 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2012-08-28 14:30:31 -0400
commitd53d04473e0d6ca1765f1117072eec59187a7f7b (patch)
treed336db3bfb308b14ec5bba88e8f4ddee1dde8899 /src/cpu/o3
parentd14e5857c7e1ee053fb4eb448c4776d7c985c5b2 (diff)
downloadgem5-d53d04473e0d6ca1765f1117072eec59187a7f7b.tar.xz
Clock: Rework clocks to avoid tick-to-cycle transformations
This patch introduces the notion of a clock update function that aims to avoid costly divisions when turning the current tick into a cycle. Each clocked object advances a private (hidden) cycle member and a tick member and uses these to implement functions for getting the tick of the next cycle, or the tick of a cycle some time in the future. In the different modules using the clocks, changes are made to avoid counting in ticks only to later translate to cycles. There are a few oddities in how the O3 and inorder CPU count idle cycles, as seen by a few locations where a cycle is subtracted in the calculation. This is done such that the regression does not change any stats, but should be revisited in a future patch. Another, much needed, change that is not done as part of this patch is to introduce a new typedef uint64_t Cycle to be able to at least hint at the unit of the variables counting Ticks vs Cycles. This will be done as a follow-up patch. As an additional follow up, the thread context still uses ticks for the book keeping of last activate and last suspend and this should probably also be changed into cycles as well.
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/O3CPU.py4
-rw-r--r--src/cpu/o3/commit.hh2
-rw-r--r--src/cpu/o3/commit_impl.hh3
-rw-r--r--src/cpu/o3/cpu.cc24
-rw-r--r--src/cpu/o3/cpu.hh12
-rw-r--r--src/cpu/o3/fetch_impl.hh2
-rw-r--r--src/cpu/o3/inst_queue_impl.hh2
-rw-r--r--src/cpu/o3/lsq_unit.hh2
8 files changed, 28 insertions, 23 deletions
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index 3138aebbf..9306cb44e 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -76,8 +76,8 @@ class DerivO3CPU(BaseCPU):
renameToROBDelay = Param.Unsigned(1, "Rename to reorder buffer delay")
commitWidth = Param.Unsigned(8, "Commit width")
squashWidth = Param.Unsigned(8, "Squash width")
- trapLatency = Param.Tick(13, "Trap latency")
- fetchTrapLatency = Param.Tick(1, "Fetch trap latency")
+ trapLatency = Param.Unsigned(13, "Trap latency")
+ fetchTrapLatency = Param.Unsigned(1, "Fetch trap latency")
backComSize = Param.Unsigned(5, "Time buffer size for backwards communication")
forwardComSize = Param.Unsigned(5, "Time buffer size for forward communication")
diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh
index b5539c702..1119e8b50 100644
--- a/src/cpu/o3/commit.hh
+++ b/src/cpu/o3/commit.hh
@@ -409,7 +409,7 @@ class DefaultCommit
/** The latency to handle a trap. Used when scheduling trap
* squash event.
*/
- Tick trapLatency;
+ uint trapLatency;
/** The interrupt fault. */
Fault interrupt;
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 31398c3d9..66474c05f 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -374,7 +374,6 @@ DefaultCommit<Impl>::initStage()
cpu->activateStage(O3CPU::CommitIdx);
cpu->activityThisCycle();
- trapLatency = cpu->ticks(trapLatency);
}
template <class Impl>
@@ -509,7 +508,7 @@ DefaultCommit<Impl>::generateTrapEvent(ThreadID tid)
TrapEvent *trap = new TrapEvent(this, tid);
- cpu->schedule(trap, curTick() + trapLatency);
+ cpu->schedule(trap, cpu->clockEdge(trapLatency));
trapInFlight[tid] = true;
thread[tid]->trapPending = true;
}
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 71d04740c..95683a77a 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -386,7 +386,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
// Setup the ROB for whichever stages need it.
commit.setROB(&rob);
- lastRunningCycle = curTick();
+ lastRunningCycle = curCycle();
lastActivatedCycle = 0;
#if 0
@@ -623,13 +623,13 @@ FullO3CPU<Impl>::tick()
getState() == SimObject::Drained) {
DPRINTF(O3CPU, "Switched out!\n");
// increment stat
- lastRunningCycle = curTick();
+ lastRunningCycle = curCycle();
} else if (!activityRec.active() || _status == Idle) {
DPRINTF(O3CPU, "Idle!\n");
- lastRunningCycle = curTick();
+ lastRunningCycle = curCycle();
timesIdled++;
} else {
- schedule(tickEvent, nextCycle(curTick() + ticks(1)));
+ schedule(tickEvent, clockEdge(1));
DPRINTF(O3CPU, "Scheduling next tick!\n");
}
}
@@ -762,7 +762,10 @@ FullO3CPU<Impl>::activateContext(ThreadID tid, int delay)
activityRec.activity();
fetch.wakeFromQuiesce();
- quiesceCycles += tickToCycles((curTick() - 1) - lastRunningCycle);
+ Tick cycles = curCycle() - lastRunningCycle;
+ if (cycles != 0)
+ --cycles;
+ quiesceCycles += cycles;
lastActivatedCycle = curTick();
@@ -801,7 +804,7 @@ FullO3CPU<Impl>::suspendContext(ThreadID tid)
unscheduleTickEvent();
DPRINTF(Quiesce, "Suspending Context\n");
- lastRunningCycle = curTick();
+ lastRunningCycle = curCycle();
_status = Idle;
}
@@ -1275,7 +1278,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
if (!tickEvent.scheduled())
schedule(tickEvent, nextCycle());
- lastRunningCycle = curTick();
+ lastRunningCycle = curCycle();
}
template <class Impl>
@@ -1669,8 +1672,11 @@ FullO3CPU<Impl>::wakeCPU()
DPRINTF(Activity, "Waking up CPU\n");
- idleCycles += tickToCycles((curTick() - 1) - lastRunningCycle);
- numCycles += tickToCycles((curTick() - 1) - lastRunningCycle);
+ Tick cycles = curCycle() - lastRunningCycle;
+ if (cycles != 0)
+ --cycles;
+ idleCycles += cycles;
+ numCycles += cycles;
schedule(tickEvent, nextCycle());
}
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index b1fd12a2e..5910f314d 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -214,9 +214,9 @@ class FullO3CPU : public BaseO3CPU
void scheduleTickEvent(int delay)
{
if (tickEvent.squashed())
- reschedule(tickEvent, nextCycle(curTick() + ticks(delay)));
+ reschedule(tickEvent, clockEdge(delay));
else if (!tickEvent.scheduled())
- schedule(tickEvent, nextCycle(curTick() + ticks(delay)));
+ schedule(tickEvent, clockEdge(delay));
}
/** Unschedule tick event, regardless of its current state. */
@@ -256,9 +256,9 @@ class FullO3CPU : public BaseO3CPU
// Schedule thread to activate, regardless of its current state.
if (activateThreadEvent[tid].squashed())
reschedule(activateThreadEvent[tid],
- nextCycle(curTick() + ticks(delay)));
+ clockEdge(delay));
else if (!activateThreadEvent[tid].scheduled()) {
- Tick when = nextCycle(curTick() + ticks(delay));
+ Tick when = clockEdge(delay);
// Check if the deallocateEvent is also scheduled, and make
// sure they do not happen at same time causing a sleep that
@@ -319,10 +319,10 @@ class FullO3CPU : public BaseO3CPU
// Schedule thread to activate, regardless of its current state.
if (deallocateContextEvent[tid].squashed())
reschedule(deallocateContextEvent[tid],
- nextCycle(curTick() + ticks(delay)));
+ clockEdge(delay));
else if (!deallocateContextEvent[tid].scheduled())
schedule(deallocateContextEvent[tid],
- nextCycle(curTick() + ticks(delay)));
+ clockEdge(delay));
}
/** Unschedule thread deallocation in CPU */
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index caafa3fe3..9caf0c79b 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -646,7 +646,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
assert(!finishTranslationEvent.scheduled());
finishTranslationEvent.setFault(fault);
finishTranslationEvent.setReq(mem_req);
- cpu->schedule(finishTranslationEvent, cpu->nextCycle(curTick() + cpu->ticks(1)));
+ cpu->schedule(finishTranslationEvent, cpu->clockEdge(1));
return;
}
DPRINTF(Fetch, "[tid:%i] Got back req with addr %#x but expected %#x\n",
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index ae5f93c38..b6c3bd239 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -828,7 +828,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
FUCompletion *execution = new FUCompletion(issuing_inst,
idx, this);
- cpu->schedule(execution, curTick() + cpu->ticks(op_latency - 1));
+ cpu->schedule(execution, cpu->clockEdge(op_latency - 1));
// @todo: Enforce that issue_latency == 1 or op_latency
if (issue_latency > 1) {
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index b886a2259..c567341c7 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -632,7 +632,7 @@ LSQUnit<Impl>::read(Request *req, Request *sreqLow, Request *sreqHigh,
delete snd_data_pkt;
}
WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this);
- cpu->schedule(wb, curTick() + delay);
+ cpu->schedule(wb, cpu->clockEdge(delay));
return NoFault;
}