It only has to be threadsafe if your Problem classes will modify it
during the execution of Problem.evaluate(...) . If they're all
READING it during then, you don't have to mutex it at all. Since
it's *data*, I had presumed that this is in fact the case.
If you want one instance per thread, then you have two choices:
1. Create an array of items in your Problem class during setup()
rather than a single item. The array should be state.evalthreads
in size. Let's call the array instance variable foo. Then during
Problem.evaluate, you use foo[threadnum] as your item. That's the
reason you're given threadnum -- so you can do this disambiguation on
a per-thread basis.
2. [SIMPLER BUT MORE COSTLY] Just have Problem.clone() copy the
data. The point here is that before Problems are handed to threads,
they're each cloned off of the prototypical Problem. So if you copy
the data during clone, then each thread has its own copy. Of course,
this means you have to copy it evalthreads times per generation. If
it's a big chunk of data, this may not be acceptable. For little
data, it's far clearer than #1 above and it's what I use throughout
in ECJ. Let's say that you've stored your data in the variable bar.
You might write
public Object clone()
{
MyProblem p = (MyProblem)(super.clone());
p.bar = (MyData)(this.bar.clone()); /* or copy it however */
return p;
}
Sean
On Dec 7, 2007, at 4:24 AM, Andrew Marshall wrote:
> Hi Sean,
>
> This is of interest to me also. If I have some static data I want
> available
> to all nodes, I can place it in the Problem class and not clone it
> as you
> suggest. However, does this data then have to be thread safe? Say I
> actually
> want one instance per thread, similar to the RNG in the EvolutionState
> class. Would it then be best to derive a new EvolutionState class?
>
> Thanks,
> Andrew.
>
> -----Original Message-----
> From: Sean Luke [mailto:[log in to unmask]]
> Sent: 07 December 2007 04:53
> Subject: Re: Execute Code at Beginning of Run?
>
> There are lots of possible places. But my top choice: in the setup()
> method of your Problem. Problem is a Prototype, so one Problem will
> be instantiated, then setup() will be called on it, then clone() will
> be called on it many times and ECJ will use the clones. If you wish
> all your Problem instances to share your data, then put it in an
> instance variable during setup(), and don't touch the variable during
> clone(). If you wish your Problem instances to have their own
> copies, then copy the variable to the cloned object during clone().
> Be sure to call super.clone(). See Prototype for more info.
>
> Sean
>
> On Dec 6, 2007, at 11:04 PM, Michael B Sullivan wrote:
>
>> Hi All,
>>
>> I have a simple question: What would be the best way to have some
>> initialization code called at the beginning of an ECJ run (before
>> the evaluation threads are spawned)?
>>
>> I have an evaluation function which requires data to be loaded into
>> memory before the first time it is run. Currently, I have it such
>> that the data is loaded upon the first time it is called, but I
>> could load the data through an initialization function (or some
>> equivalent), if necessary.
>>
>> My problem is that a multithreaded ECJ run will call the function
>> multiple times before the data is fully loaded into memory,
>> resulting in ugly results for the first couple evaluations.
>>
>> If this issue doesn't fit nicely into the ECJ world view, I can fix
>> it with mutex locks, etc. However, if there's an easy way to
>> execute code at the beginning of an ECJ run, I would love to hear it.
>>
>> Thanks!
>> Mike
|