Hi Andy, cej38, kovas: Thanks for the replies. I plan to release the whole code soon (waiting for institutional authorization).
I do use lazyness both within the move function to select the allowed random displacements and when iterating the move function to generate the trajectory. Lazy structures are only consumed within the thread in which they are created. Here is the core code where the computations happens: (defn step-particle "Returns a new value for particle after moving particle once to a new position from the current one" [pdf-get-fn step-condition-fn calc-value-fns particle] (let [pos (particle :pos) disp (first (filter (fn [x] (step-condition-fn (particle :pos) x)) (repeatedly (fn [] (pdf-get-fn))))) new-pos (mapv + pos disp) new-base-particle {:pos new-pos :steps (inc (particle :steps))} new-trackers-results (if (seq calc-value-fns) (zipmap (keys calc-value-fns) ((apply juxt (vals calc-value-fns)) particle new-base-particle)) {})] (merge new-trackers-results new-base-particle))) (defn walk-particles "While there is work to do, create new particles, move them n-steps, then send them to particle container (agent)" [todo particles simul-info init-get-fn init-condition step-get-fn step-condition trackers-maps step-extract-fn] (let [init-value-fns (zipmap (keys trackers-maps) (map :create-fn (vals trackers-maps))) calc-value-fns (zipmap (keys trackers-maps) (map :compute-fn (vals trackers-maps))) move (partial step-particle step-get-fn step-condition calc-value-fns)] (while (> @todo 0) (swap! todo dec) (let [p (last (create-particle init-get-fn init-condition init-value-fns)) lazy-steps (iterate move p) result (step-extract-fn lazy-steps)] (send-off particles (fn [x] (conj x result))) )))) Each worker is created launching a future that executes walk-particles, each worker has a separate Mersenne Twister random number generator embedded into the pdf-get-fn (using partial on a common pdf-get function and different MT generators). In real calculations both number of particles and steps are at least 1e4. In the benchmarks I'm posting particles are 1000, steps are 5000. As expected conjoining to a single global vector poses no problem, I tested both conjoining to a single global vector and to separate global vectors (one per worker) and the computing time is the same. I could test in another system with 16 cores. See the results attached for the 8 and 16 core systems. Best, Jose. -- -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
benchmark.pdf
Description: Adobe PDF document