On Fri, Jun 24, 2011 at 9:16 AM, Beckmann, Brad <[email protected]>wrote:

> Hi Somayeh,
>
> Thanks for the questions.  We definitely want to make sure we're all on the
> same page before we start coding.  My answers are below:
>
> > why do you think we need to ensure that there is no event scheduled for
> > ticks T or more? We only need to make sure all Ruby cache warmup events
> > are done before T regardless of what have been scheduled for after that.
>
> Sorry for the confusion.  You are right that other events may be scheduled
> for ticks T or more.  In particular, during the unserialization phase, I
> suspect several events will be placed on the event queue for tick T or more.
>  There may even be other events put on the event queue for tick T or more
> during other SimObjects' startup routines.  The key is that we should make
> sure during the cache warmup phase (within Topology::startup) that all
> events scheduled are for ticks T-1 or less.
>

> > What if T is not large enough to finish cache warmup? do we need to stop
> > other scheduled events?!
>
> We need to call fatal and return a description that T is not large enough
> (include the value of T in the error message).
>

I agree with what Brad is saying, but just to be crystal clear on the
mechanism: I believe that resetting curTick to 0 and calling simulate(T-1)
should be adequate, as it will force us out of the simulation loop at T-1
whether or not the Ruby transaction is complete.  If we hit T-1 and the
transaction is not complete, then we can call fatal.  As long as there are
no Ruby components that schedule events past the completion of a
transaction, this should be safe.  If there is a chance that additional
events could be scheduled (e.g., replacement writebacks?) then we would need
to have a way to check that Ruby is completely idle at T-1.

I think it would be awkward to have a mode where we test every event that's
scheduled to make sure it doesn't have a timestamp that goes past T.  If we
decide that something like that is really necessary, then I might consider
switching to Nate's idea of just using a separate event queue.  Another
possibility that might be a little easier to code than having to walk all of
the Ruby objects and switch their event queue pointer would be to
temporarily move the existing events out of the way, then restore them at
the end.  Hmm, now that I said that, that sounds pretty appealing... it's
easy to do since the event queue is basically a linked list (just save the
head pointer somewhere and replace it with NULL).  How's this for another
option (still called from someone's startup() method):

   1. Save the (already restored) curTick() value (call this T).
   2. Save the event queue head pointer value, replace with NULL (will need
to add an EventQueue method for this, since head is private).
   3. Set curTick to 0 (optional, but might be useful even if just to make
it obvious that this isn't the real simulation)
   4. Schedule and event to inject the first transaction at time 0 (or T if
we didn't reset curTick, or maybe just inject it directly?)
   5. Call simulate()
        5.1. In the callback function as each transaction completes, inject
the next transaction.
        5.2. When there are no more transactions, either call exitSimLoop()
directly or just wait for the MAXINT event that simulate() schedules to kick
us out of the loop.  (I think the latter is safer, since it guarantees that
any trailing events like writebacks will complete.)
   6. Restore event queue head pointer.
   7. Re-restore curTick to T.

Thoughts?

Steve
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to