Context :

I'm currently comparing (ease of implementation *and* performance) C++
and Clojure (no flame war intented :  I *love* them both) trying to
find when / how one can code in Clojure rather than in C++.

Problem :

Rewriting some financial computing code, I was very pleased with my
first shot [0] (no type hinting yet, on Clojure 1.2) being only x6
slower than C++ with maximal optimizations (-march=native -O4) : the
JIT really shines here !

However, this is only for single core C++, as both OpenMP [1] and
C++0X [2] allow me to get a further x3 advantage on my netbook, as the
algorithm is embarrassingly parallel.

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.
So each thread should have its own rng, but those rng should not be
clones of each other because there would be no point in running
multiple computations on the same sequences of pseudo-random numbers !

In my C++ implementations, I solve this easily with local copies of
the rng that reseed themselves (from a shared counter : the contention
upon seeding can easily be afforded) upon copy.

In Clojure, this means that a parallel outer reduce (is it even
possible ? I see a clojure.core/pmap but no preduce) over a single
random numbers sequence would be suboptimal. However, I have no clue
about how to tackle this problem : could someone clue me in ?

This key code from [0] is :
      (map f (reduce combine [0. 0.]
                     (partition n-steps (sample-normal (* n-steps num-
trials)
                                                       :mean 0. :sd
volatility)))))))
each combine invocation consuming n-steps random numbers.

I see how I could seed the thread local rng with local
cern.jet.random.tdouble.engine.DoubleMersenneTwister but not the
generic design in which I could have a pool of worker threads sharing
the work, each with its own rng (not just copies, but independently
seeded).
(I have an idea but it seems very ugly and required a complete rewrite
so I hope there would be a better way).

Any idea most welcome !
(I'd *love* to get back with 10x of the fastest C++, I find the
Clojure Way so joyful :-) )

Best Regards,

Bernard

PS: I'll move to Clojure 1.3 for type hinting, are there any pitfalls
in using Incanter lib with Clojure 1.3 ? (Is it at all
possible ? :-) )

PS2: My next implementation will be in OpenCL : is calx the best
OpenCL
wrapper ?

[0]
https://github.com/scientific-coder/Black-Scholes/blob/master/src/incanter-montecarlo.clj

[1]
https://github.com/scientific-coder/Black-Scholes/blob/master/src/openmp-montecarlo.cxx

[2]
https://github.com/scientific-coder/Black-Scholes/blob/master/src/cxx0x-montecarlo.cxx

[3] no hard numbers because g++ so agressively inlines the rng that
the random number generation in intermixed with further computations !
But perf reports 80% cpu usage in this spot.

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