summaryrefslogtreecommitdiff
path: root/src/sim/clocked_object.hh
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/sim/clocked_object.hh
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/sim/clocked_object.hh')
-rw-r--r--src/sim/clocked_object.hh89
1 files changed, 73 insertions, 16 deletions
diff --git a/src/sim/clocked_object.hh b/src/sim/clocked_object.hh
index 8ab637772..050a15a74 100644
--- a/src/sim/clocked_object.hh
+++ b/src/sim/clocked_object.hh
@@ -58,6 +58,14 @@ class ClockedObject : public SimObject
private:
+ // the tick value of the next clock edge (>= curTick()) at the
+ // time of the last call to update()
+ mutable Tick tick;
+
+ // The cycle counter value corresponding to the current value of
+ // 'tick'
+ mutable Tick cycle;
+
/**
* Prevent inadvertent use of the copy constructor and assignment
* operator by making them private.
@@ -65,6 +73,34 @@ class ClockedObject : public SimObject
ClockedObject(ClockedObject&);
ClockedObject& operator=(ClockedObject&);
+ /**
+ * Align cycle and tick to the next clock edge if not already done.
+ */
+ void update() const
+ {
+ // both tick and cycle are up-to-date and we are done, note
+ // that the >= is important as it captures cases where tick
+ // has already passed curTick()
+ if (tick >= curTick())
+ return;
+
+ // optimise for the common case and see if the tick should be
+ // advanced by a single clock period
+ tick += clock;
+ ++cycle;
+
+ // see if we are done at this point
+ if (tick >= curTick())
+ return;
+
+ // if not, we have to recalculate the cycle and tick, we
+ // perform the calculations in terms of relative cycles to
+ // allow changes to the clock period in the future
+ Tick elapsedCycles = divCeil(curTick() - tick, clock);
+ cycle += elapsedCycles;
+ tick += elapsedCycles * clock;
+ }
+
protected:
// Clock period in ticks
@@ -74,7 +110,8 @@ class ClockedObject : public SimObject
* Create a clocked object and set the clock based on the
* parameters.
*/
- ClockedObject(const ClockedObjectParams* p) : SimObject(p), clock(p->clock)
+ ClockedObject(const ClockedObjectParams* p) :
+ SimObject(p), tick(0), cycle(0), clock(p->clock)
{ }
/**
@@ -85,33 +122,53 @@ class ClockedObject : public SimObject
public:
/**
- * Based on the clock of the object, determine the tick when the
- * next cycle begins, in other words, round the curTick() to the
- * next tick that is a multiple of the clock.
+ * Determine the tick when a cycle begins, by default the current
+ * one, but the argument also enables the caller to determine a
+ * future cycle.
*
- * @return The tick when the next cycle starts
+ * @param cycles The number of cycles into the future
+ *
+ * @return The tick when the clock edge occurs
*/
- Tick nextCycle() const
- { return divCeil(curTick(), clock) * clock; }
+ inline Tick clockEdge(int cycles = 0) const
+ {
+ // align tick to the next clock edge
+ update();
+
+ // figure out when this future cycle is
+ return tick + ticks(cycles);
+ }
/**
- * Determine the next cycle starting from a given tick instead of
- * curTick().
+ * Determine the current cycle, corresponding to a tick aligned to
+ * a clock edge.
*
- * @param begin_tick The tick to round to a clock edge
+ * @return The current cycle
+ */
+ inline Tick curCycle() const
+ {
+ // align cycle to the next clock edge.
+ update();
+
+ return cycle;
+ }
+
+ /**
+ * Based on the clock of the object, determine the tick when the
+ * next cycle begins, in other words, return the next clock edge.
*
- * @return The tick when the cycle after or on begin_tick starts
+ * @return The tick when the next cycle starts
*/
- Tick nextCycle(Tick begin_tick) const
- { return divCeil(begin_tick, clock) * clock; }
+ Tick nextCycle() const
+ { return clockEdge(); }
inline Tick frequency() const { return SimClock::Frequency / clock; }
- inline Tick ticks(int numCycles) const { return clock * numCycles; }
+ inline Tick ticks(int cycles) const { return clock * cycles; }
- inline Tick curCycle() const { return curTick() / clock; }
+ inline Tick clockPeriod() const { return clock; }
- inline Tick tickToCycles(Tick val) const { return val / clock; }
+ inline Tick tickToCycle(Tick tick) const { return tick / clock; }
};