I noticed with the working pdoseq I posted earlier that sometimes the
threads on one core get ahead of those on the others, for some reason,
and then that core is idle for the rest of a job -- Windows, at least,
doesn't seem to reassign one or more threads to the freed core. So I
wrote this version:

(defmacro pdoseq
  "Bindings as for for, but parallel execution as per pmap, pcalls,
pvalues; returns
   nil."
  [seq-exprs & body]
  `(let [procs# (+ 2 (.availableProcessors (Runtime/getRuntime)))
         calls# (for ~seq-exprs (fn [] ~@body))
         chunks# (atom [nil (partition 100 calls#)])
         threads# (for [i# (range procs#)]
                    (Thread.
                      #(loop []
                         (let [chunk# (first
                                        (swap! chunks# (fn [[_# [a# &
b#]]] [a# b#])))]
                           (when chunk#
                             (doall
                               (map (fn [x#] (x#)) chunk#))
                             (recur))))))]
     (doseq [t# threads#]
       (.start t#))
     (doseq [t# threads#]
       (.join t#))))

This one replaces the interleaving with a job queue, which each thread
atomically takes from. The input items are chunked into hundreds in
the code above, but that number can easily be changed (or even made
into a parameter of the macro). I think this should divide the work up
more evenly among the available cores until nearly the end (if there
are thousands or more of calls in calls#) when there will eventually
be no chunks left unassigned and worker threads becoming idle.

In case anyone might find this useful, I'm relinquishing any copyright
in either version and placing both into the public domain for others
to freely reuse.

-- 
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