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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en