[MLton-commit] r5719
Vesa Karvonen
vesak at mlton.org
Tue Jul 3 06:30:47 PDT 2007
Changed to conform more closely to the spec.
----------------------------------------------------------------------
U mltonlib/trunk/org/mlton/vesak/toys/cheap-concurrency/async/cheap-concurrency.sml
----------------------------------------------------------------------
Modified: mltonlib/trunk/org/mlton/vesak/toys/cheap-concurrency/async/cheap-concurrency.sml
===================================================================
--- mltonlib/trunk/org/mlton/vesak/toys/cheap-concurrency/async/cheap-concurrency.sml 2007-07-03 11:16:32 UTC (rev 5718)
+++ mltonlib/trunk/org/mlton/vesak/toys/cheap-concurrency/async/cheap-concurrency.sml 2007-07-03 13:30:46 UTC (rev 5719)
@@ -7,31 +7,52 @@
(*
* This is basically an implementation of the Cheap Concurrency toy
* benchmark, from the ``Computer Language Benchmarks Game'', using a
- * library for portable asynchronous programming in SML. This
- * implementation was inspired by a Haskell implementation by Einar
- * Karttunen, Simon Marlow, and Don Stewart. The Async library does not
- * use threads or processes of any kind. Measure the performance
- * yourself!
+ * library for portable asynchronous programming in SML. The Async
+ * library does not use threads or processes of any kind. Measure the
+ * performance yourself!
*)
open Async
+(* Makes a single handler that takes an integer message from a
+ * channel, increments it, and gives it to another channel. *)
fun handler im = let
- val om = MVar.new ()
+ val om = Ch.new ()
+ fun lp () =
+ when (Ch.take im)
+ (fn x =>
+ when (Ch.give om (x+1))
+ lp)
in
- every (MVar.take im) (fn x => MVar.fill om (x+1))
- ; om
+ lp () ; om
end
-val head = MVar.new ()
+(* Makes a chain (head -> ... -> tail) of 500 handlers. *)
+val head = Ch.new ()
val tail = repeat handler 500 head
-fun accumulate n sum =
+(* An utility function for repeating an event a given number of times. *)
+fun rept event combine finish n s =
if n = 0
- then println (Int.toString sum)
- else (MVar.fill head sum
- ; when (MVar.take tail) (accumulate (n-1)))
+ then finish s
+ else when event (fn x => rept event combine finish (n-1) (combine (x, s)))
+(* Gets the number of times to pass a message through the chain. *)
val n = valOf (Int.fromString (hd (CommandLine.arguments ()))) handle _ => 1
-val () = (accumulate n 0 ; Handler.runAll ())
+(* Initiates a sequence of events that gives a 0 message to the head of
+ * the chain n times and another sequence of events that takes a message
+ * from the tail of the chain n times, accumulating them, and finally
+ * printing the result. Then runs all handlers to process the events. *)
+val () =
+ (rept (Ch.give head 0) ignore ignore n ()
+ ; rept (Ch.take tail) op + (println o Int.toString) n 0
+ ; Handler.runAll ())
+
+(* PERFORMANCE ANALYSIS
+ *
+ * This implementation spends a lot of time doing GC (> 40%) although
+ * the max live usage is small and stays roughly constant. With a
+ * number of optimizations to the Async library, the GC time could
+ * probably be reduced significantly.
+ *)
More information about the MLton-commit
mailing list