[Haskell-cafe] An interesting toy
Derek Elkins
derek.a.elkins at gmail.com
Sat May 5 16:33:03 EDT 2007
Andrew Coppin wrote:
> Greetings.
>
> I have something which you might find mildly interesting. (Please don't
> attempt the following unless you have some serious CPU power available,
> and several hundred MB of hard drive space free.)
>
> darcs get http://www.orphi.me.uk/darcs/Chaos
> cd Chaos
> ghc -O2 --make System1
> ./System1
>
> On my super-hyper-monster machine, the program takes an entire 15
> minutes to run to completion. When it's done, you should have 500 images
> sitting in front of you. (They're in PPM format - hence the several
> hundred MB of disk space!) The images are the frames that make up an
> animation; if you can find a way to "play" this animation, you'll be
> treated to a truely psychedelic light show! (If not then you'll just
> have to admire them one at a time. The first few dozen frames are quite
> boring by the way...)
>
> If you want to, you can change the image size. For example, "./System1
> 800" will render at 800x800 pixels instead of the default 200x200. (Be
> prepaired for /big/ slowdowns!)
>
> *What is it?*
>
> Well, it's a physical simulation of a "chaos pendulum". That is, a
> magnetic pendulum suspended over a set of magnets. The pendulum would
> just swing back and forth, but the magnets perturb its path in complex
> and unpredictable ways.
>
> However, rather than simulate just 1 pendulum, the program simulates
> 40,000 of them, all at once! For each pixel, a pendulum is initialised
> with a velocity of zero and an initial position corresponding to the
> pixel coordinates. As the pendulums swing, each pixel is coloured
> according to the proximity of the corresponding pendulum to the tree
> magnets.
>
> *Help requested...*
>
> Can anybody tell me how to make the program go faster?
>
> I already replaced all the lists with IOUArrays, which resulted in big,
> big speedups (and a large decrease in memory usage). But I don't know
> how to make it go any faster. I find it worrying that the process of
> converting pendulum positions to colours appears to take significantly
> longer than the much more complex task of performing the numerical
> integration to discover the new pendulum positions. Indeed, using GHC's
> profiling tools indicates that the most time is spent executing the
> function "quant8". This function is defined as:
>
> quant8 :: Double -> Word8
> quant8 = floor . (0xFF *)
>
> I can't begin to /imagine/ how /this/ can be the most compute-intensive
> part of the program when I've got all sorts of heavy metal maths going
> on with the numerical integration and so forth...! Anyway, if anybody
> can tell me how to make it run faster, I'd be most appriciative!
>
> Also, is there an easy way to make the program use /both/ of the CPUs in
> my PC? (Given that the program maps two functions over two big IOUArrays...)
>
> Finally, if anybody has any random comments about the [lack of] qualify
> in my source code, feel free...
Try adding strictness annotations to all the components of all your data
structures (i.e. put a ! before the type). Not all of the need it, but I doubt
any need to be lazy either. Probably the reason quant8 seems to be taking so
much time is that it is where a lot of stuff finally gets forced. Certainly,
for things that are "primitive" like Colour and Vector you want the components
to be strict, in general.
I did this for the program and ran System1 100 and it took maybe a couple of
minutes, it seemed to be going at a decent clip. 200x200 should take 4 times
longer, I assume, and I still don't see that taking 15 minutes. This is on a
laptop running on a Mobile AMD Sempron 3500+. Also, you have many many
superfluous parentheses and use a different naming convention from
representative Haskell code (namely camelCase).
More information about the Haskell-Cafe
mailing list