Hi, sorry to be late to the party...
Please let me try to answer some of your questions in one post. 1. The main purpose for the code was to show how many threads could work on one shared data-structure and how the introduction of concurrent programming can change the algorithms: in this case moving from generations of populations to one population being continuously changed by threads. In addition to that I wanted to demo the concept of self-calling agents while another agent indicates the current state of the whole system. 2. The problem with the increasing of the population depending on the number of threads for creating new individuals and removing other from the population was initially unforeseen. However, I kept it in the book because it indicates that there are new issues for the programmer to handle, when concurrent programming is introduced. In addition to that, I personally think that the management of resources like seen in this example will become an issues as soon as we are talking about more than -say- 16 cores. I think we will need more control than just one thread pool. 3. This examples does not use Refs and thus it has nothing to do with the integration of agents into the STM system. BTW the integration means that the STM will take care that any function sent to an agent within a transaction will only be sent exactly one, not for every retry of the dosync-body. 4. When I wrote the code it usually evolved within some 10-20 seconds. On a dual core machine. I wouldn't have put code in the book that took several minutes on my machines. So, I wonder why it is so slow on your machines. (Sidenote: I'd expect a reasonably well tunes GA written single-threadedly in C to find the solution in a few seconds at max.) 5. The pmap that you introduced when sending the functions to the agents would only queue the functions faster, as Jim mentioned in his last post. In my understanding that should not really make any difference. The overhead in that piece of code would be small, because it is only created once, not in a tight loop or something. The increase of memory *might* be related to garbage collection being too slow. Did you try to use parallel GC? 6. My use of send-off in the grim reaper agent fn is an error. send-off is supposed to be used for potentially blocking functions, e.g. I/O. Maybe this one is the reason for the problems with growing populations? send-off uses a different thread pool which is not of fixed size (IIRC). I will have to try that out, but it will take a few days. 7. The whole example is rather artificial: usually the fitness function would be expensive, whereas in this example it is just boils down to some cheap comparisons. Thus, there will probably be many collisions when trying to change the population Atom. This would decrease the amount of concurrency that is possible. You might want to try to apply the general GA idea to a more complicated problem which makes the calculation of the fitness more expensive. In that case the reading an writing on the atom would become less, compared to the calculation of the fitness, thereby reducing the amount of collisions and repetitions of the update function. After all that has been said, I sincerely hope, that playing with that example helped you understand things better. :-) Kind regards, Stefan -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en