Could someone who has a machine with more than 2 cores please
run the following code? It calculates the inner product of two given
vectors.
Usage: (inner-product [1 2 3] [4 5 6]) => 32

You can change the "9000" which is sprinkled over the code (I know
it's not beautiful, but I'm new to clojure so
please go easy...). This number defines the max. length of a pair of
sub vectors, which is then given to an
agent as its initial state, whereafter the "dot-product" function is
send to that agent.
I have a 2 core machine with 6 MB shared level 2 cache. So I suppose
that an agent which holds 18000 (9000 integers a vector)
should fit easily into 3 MB level 2 cache. When I run the commented
code at the bottom,
"dot-product" performs better. It would be interesting to see whether
this changes on 4 or 8 core machines.

My Setup:
CPU: 2.53 GHz
RAM: 4 GByte, 1067 MHz
Mac OS X 10.5.6
java version 1.6.0_07

I run the code with "java -server".

Thank you, Oliver.




(defn- dot-product
  "Takes two vectors and returns their dot product.
    For example: (dot-product [1 2 3] [4 5 6]) => 32"
    ([vector1 vector2] (reduce + (map * vector1 vector2)))
    ([sequence] (dot-product (first sequence) (second sequence))))

;; The '9000' in next two function definitions is the lenght of a sub-
vector which should fit(?) in the level 2 cache.

(defn- create-agent-send-dot-product! [set-with-agents remaining-
vector1 remaining-vector2]
  "Takes a set which contains agents and two vectors of numbers, then
(as a SIDE EFFECT)
   creates an agent(with a list of the two vectors as an initial
state) and sends it the 'dot-product' function.
   It then returns a new set by conjing the created agent to the
supplied set."
  (conj set-with-agents (send (agent (map vec (list (take 9000
remaining-vector1) (take 9000 remaining-vector2)))) dot-product)))


(defn inner-product [vector1 vector2]
  (loop [number-of-agents (quot (count vector1) 9000)
         set-with-agents #{}
         remaining-vector1 vector1
         remaining-vector2 vector2]
         (if (zero? number-of-agents)
           (do (apply await set-with-agents)
               (reduce + (conj (map deref set-with-agents) (dot-
product remaining-vector1 remaining-vector2))))
         (recur (dec number-of-agents)
                (create-agent-send-dot-product! set-with-agents
remaining-vector1 remaining-vector2)
                (drop 9000 remaining-vector1)
                (drop 9000 remaining-vector2)))))



(comment

(def vec1 (doall (range 7000000)))
(def vec2 (doall (range 7000000)))

(time (dot-product vec1 vec2))      ;; Single threaded calculation. =>
3722 msec
(time (inner-product vec1 vec2))    ;; Multi threaded calculation. =>
4452 msec

)

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