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

Reply via email to