On Jul 22, 2011, at 11:20 AM, bernardH wrote: > > But there is a small catch : most of the time is spent in the Random > Number Generator [3] so it would be sub-optimal to just have worker > threads processing the output of a single threaded rng.
I am not very confident in my solution to a similar problem, and my application makes measurement difficult, but in case it's food for thought what I did was the following, using the standard Java rng: ;; create a root binding for the "thread-local-random-generator", although this won't be used in the distributed code: (def thread-local-random-generator (new java.util.Random)) ;; create some work-alikes to rand-int and lrand-int that use the thread local generator (defn lrand-int "Return a random integer, using the thread-local random generator, that is less than the provided n. Arguments greater than 2^31-1 are treated as if they were 2^31-1 (2147483647)." [n] (if (<= n 1) 0 (if (= (type n) java.lang.Integer) (. thread-local-random-generator (nextInt n)) (. thread-local-random-generator (nextInt 2147483647))))) ;; biggest java.lang.Integer (defn lrand "Return a random float between 0 and 1 usng the thread-local random generator." ([] (. thread-local-random-generator (nextFloat))) ([n] (* n (lrand)))) ;; Then use lrand-int and lrand instead of rand-int and rand throughout my code, and, ;; for things that I'm going to want to distribute, re-bind the rng as in this example: (defn evaluate-individual "Returns the given individual with errors and total-errors, computing them if necessary." [i error-function rand-gen] (binding [thread-local-random-generator rand-gen] <details omitted>)) ;; Now the code that dispatches the distributed stuff. I do this by creating a vector of agents ;; that will do the computations and a vector of rngs that will be used in those computations, ;; like: (let [pop-agents (vec (doall (for [_ (range population-size)] (agent (make-individual :program (random-code max-points atom-generators)) :error-handler (fn [agnt except] (println except)))))) rand-gens (vec (doall (for [_ (range population-size)] (java.util.Random.))))] ;; and then to do the actual computations I have something like the following within ;; the let that I started above: (dorun (map #(send % evaluate-individual error-function %2) pop-agents rand-gens)) (apply await pop-agents) ;; SYNCHRONIZE Again, I make no claims for this, and I'd love to hear if someone sees something wrong or a simpler way to accomplish this. The larger context of the above snippets is: https://github.com/lspector/Clojush -Lee -- 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