November 2011


Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Steven Saul <[log in to unmask]>
Reply To:
MASON Multiagent Simulation Toolkit <[log in to unmask]>
Thu, 3 Nov 2011 17:24:22 -0400
text/plain (2383 bytes) , (3263 bytes)
Hi Sean,

Sorry to bother you with this, but I had a quick question regarding the
Schedule.  A while ago (back in March) you sent around a revised version
of the Schedule (called, see attached) that you were
thinking might make some people's simulations run a little faster that
have larger numbers of agents.  I was thinking of giving it a try as my
simulation represents five species of fish and two fishing fleets on the
Gulf coast of Florida (about 8 million agents).  When I dumped the file
into MASON 13, however, I got a syntax error on line 42 (which says
super.clear();) and when I dump it into MASON 16, I get a syntax error on
line 33 (which says super.pushToAfterSimulation();).  It can't seem to be
able to find or over-ride these functions in the original schedule.  Any
quick fixes?  Also, have people had much success speeding up their
simulation using this class?  Mine is multi-threaded and currently takes
about 9 hours on a 64 bit windows 7 machine that has intel's i7 processor
and 16G of memory (which I'm not complaining about given the number of
agents and calculations).  Once I clean up the code that does fish
recruitment I should be able to cut this time down a little more.

Thanks for your help,
Steve Saul

> Maciej Latek and I are working on a revised version of the Schedule
> which is somewhat more complex but is expected to perform better when
> you have larger numbers of agents and a small number of orderings per
> timestep.  The downside is that it must use a Hashtable internally to
> retain various Bags, and the hashing  provides a constant overhead.
> So it might or might not be faster for your application.
> In MASON you can just drop in a replacement for your Schedule, like
> this:
>      public HeatBugs(long seed)
>          {
>          this(seed, 100, 100, 100);
> 	schedule = new Schedule2();    // dump the old Schedule, use
> Schedule2 instead
>          }
> So this means that we might offer as an option rather
> than replacing if people like it.
> Let me know what you think -- did it make your simulation faster?
> Sean

Steven Saul, M.A.
Graduate Assistant, Marine Biology and Fisheries
Cooperative Institute for Marine and Atmospheric Studies
Cooperative Unit for Fisheries Education and Research
University of Miami - RSMAS
4600 Rickenbacker Cswy.
Miami, Florida  33149
+ 1 305-421-4831

package sim.engine; import; import sim.util.*; import ec.util.*; import java.util.*; /** This version uses a HashMap to store all current bags in the Heap. They're keyed by <time, ordering> tuples. How to use in heatbugs:     public HeatBugs(long seed)         {         this(seed, 100, 100, 100); schedule = new Schedule2(); // get rid of the schedule         } */ public class Schedule2 extends Schedule implements     { HashMap hash = new HashMap();          protected void pushToAfterSimulation()         {         synchronized(lock)             { super.pushToAfterSimulation(); hash = new HashMap();             }         }     public void clear()         {         synchronized(lock)             { super.clear(); hash = new HashMap();             }         }     public void reset()         {         synchronized(lock)             { super.reset(); hash = new HashMap();             }         }          /** Schedules an item. You must synchronize on this.lock before calling this method. This allows us to avoid synchronizing twice,         and incurring any overhead (not sure if that's an issue really). */     protected boolean _scheduleOnce(Key key, final Steppable event)         {         // locals are a teeny bit faster         double time = 0;         time = this.time;         double t = key.time;         // check to see if we're scheduling for the same exact time -- even if of different orderings, that doesn't matter         if (t == time && t != AFTER_SIMULATION)             // bump up time to the next possible item, unless we're at infinity already (AFTER_SIMULATION)             t = key.time = Double.longBitsToDouble(Double.doubleToRawLongBits(t)+1L);         if (t < EPOCH)             throw new IllegalArgumentException("For the Steppable...\n\n"+event+                 "\n\n...the time provided ("+t+") is < EPOCH (" + EPOCH + ")");         else if (t >= AFTER_SIMULATION)             throw new IllegalArgumentException("For the Steppable...\n\n"+event+                 "\n\n...the time provided ("+t+") is >= AFTER_SIMULATION (" + AFTER_SIMULATION + ")");         else if (t != t /* NaN */)             throw new IllegalArgumentException("For the Steppable...\n\n"+event+                 "\n\n...the time provided ("+t+") is NaN");         else if (t < time)             throw new IllegalArgumentException("For the Steppable...\n\n"+event+                 "\n\n...the time provided ("+t+") is less than the current time (" + time + ")");         else if (event == null)             throw new IllegalArgumentException("The provided Steppable is null");          BagSequence seq = (BagSequence)(hash.get(key)); if (seq == null) // no BagSequence, create one { seq = new BagSequence(key); hash.put(key, seq); queue.add(seq, key); } // now add the scheduled item to the bag seq.add(event);         return true;         } class BagSequence implements Steppable { Bag steps = new Bag(); Key key; public BagSequence(Key key) { this.key = key; } public void add(Steppable step) { steps.add(step); } public void step(SimState state) { hash.remove(key); // get rid of me steps.shuffle(state.random); for(int x=0;x<steps.numObjs;x++) ((Steppable)(steps.objs[x])).step(state); } }     }