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 Schedule2.java, 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 Schedule2.java as an option rather
> than replacing Schedule.java 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
http://cufer.rsmas.miami.edu
package sim.engine;
import java.io.Serializable;
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 java.io.Serializable
{
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);
}
}
}
|