[Haskell-cafe] Parallel Haskell stories

John Lato jwlato at gmail.com
Thu Mar 10 18:23:57 CET 2011

From: Simon Peyton-Jones <simonpj at microsoft.com>

> Friends
> I'm giving a talk at a developer conference in London on Friday 18th, about
> parallel programming in Haskell.
>        http://skillsmatter.com/event/scala/functionalpx-2011/ad-1382
> I know that some of you have been using Haskell for parallel or concurrent
> programming quite a bit, so this email is just to ask
>        could you contribute a little vignette or story
>        about using Haskell in a *parallel/concurrent* application
>        that I could use to illustrate my talk?

I have a physical-model-based audio synthesis application I wanted to
convert from an off-line renderer into a real-time engine.  I decided upon a
concurrent architecture with an interface thread, an engine thread, and an
output thread, using STM for communication.  It only took a couple hours to
make the conversion, most of which was spent modifying the synthesis to work
in blocks instead of a single run.

I'm particularly happy with this snippet, where the engine collects input
from the interface thread:

  readStrikeVar = do
    ct <- getCPUTime
    atomically $ rsv' ct `orElse` return []
   -- if the read fails, return an empty list because we can't afford to
   -- the strikes will eventually catch up...
  rsv' ct = do
    strikes <- readTVar tstrikes
    let carry = map (updateCarry blockdur) $ filter carryOver strikes
    writeTVar tstrikes carry
    writeTVar tsync ct
    return (reverse strikes)

This code is the most complicated part of the communication scheme, nearly
everything else is at the level of "readTVarIO".  A nice feature is that the
engine doesn't block waiting for the interface.  If the transaction fails
because the interface is updating the TVar, the engine moves ahead and can
catch up later.

On my dual-core macbook, performance is perhaps slightly disappointing
compared to the offline renderer which is single-threaded and not
parallelized.  With one simulation the offline renderer will generate 5
seconds of audio in about 3.3seconds at 100% CPU usage, giving me the
equivalent of 66% CPU over 5 seconds.  The realtime renderer consistently
occupies about 171% CPU for the same simulation.  A different simulation has
a runtime of 4.4 seconds and realtime usage of 191%.  Of course there's
going to be some overhead, but I hope to improve this by changing the way
data is fed to the engine to a TChan, and also running threadscope to make
sure threads yield at the proper times.

Speaking of which, threadscope is an awesome tool and deserves a mention.

John L.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110310/e9b2d3c2/attachment.htm>

More information about the Haskell-Cafe mailing list