Parallelize the balancing computations
authorIustin Pop <iustin@google.com>
Fri, 17 Dec 2010 15:52:40 +0000 (16:52 +0100)
committerIustin Pop <iustin@google.com>
Thu, 30 Dec 2010 13:56:37 +0000 (14:56 +0100)
This small patch changes the balancing computation to work in
parallel, if possible.

While the normal linking is against the single-threaded runtime, if
the code is linked against the multi-threaded one, the balancing will
get a significant speedup (80% efficiency at 4 cores, 60% at 12 cores,
and with GC tweaks it can reach 70%+).

On the single-threaded runtime, due to the fact that we only use the
weak head normal form, it doesn't introduce any extra penalties,
neither in space nor in CPU time (or if there are, they are too small
to detect easily).

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Balazs Lecz <leczb@google.com>

Ganeti/HTools/Cluster.hs
README

index 8a79ff9..1e111f0 100644 (file)
@@ -75,6 +75,7 @@ import Data.List
 import Data.Ord (comparing)
 import Text.Printf (printf)
 import Control.Monad
+import Control.Parallel.Strategies
 
 import qualified Ganeti.HTools.Container as Container
 import qualified Ganeti.HTools.Instance as Instance
@@ -492,13 +493,18 @@ checkMove :: [Ndx]               -- ^ Allowed target node indices
           -> Table               -- ^ The new solution
 checkMove nodes_idx disk_moves ini_tbl victims =
     let Table _ _ _ ini_plc = ini_tbl
+        -- we're using rwhnf from the Control.Parallel.Strategies
+        -- package; we don't need to use rnf as that would force too
+        -- much evaluation in single-threaded cases, and in
+        -- multi-threaded case the weak head normal form is enough to
+        -- spark the evaluation
+        tables = parMap rwhnf (checkInstanceMove nodes_idx disk_moves ini_tbl)
+                 victims
         -- iterate over all instances, computing the best move
         best_tbl =
             foldl'
-            (\ step_tbl em ->
-                 compareTables step_tbl $
-                 checkInstanceMove nodes_idx disk_moves ini_tbl em)
-            ini_tbl victims
+            (\ step_tbl new_tbl -> compareTables step_tbl new_tbl)
+            ini_tbl tables
         Table _ _ _ best_plc = best_tbl
     in if length best_plc == length ini_plc
        then ini_tbl -- no advancement
diff --git a/README b/README
index 62b9c1a..cb7f611 100644 (file)
--- a/README
+++ b/README
@@ -91,6 +91,7 @@ installed manually:
 - `json <http://hackage.haskell.org/package/json>`_
 - `curl <http://hackage.haskell.org/package/curl>`_
 - `network <http://hackage.haskell.org/package/network>`_
+- `parallel <http://hackage.haskell.org/package/parallel>`_, version 1.x
 
 Once these are installed, just typing *make* in the top-level directory
 should be enough. If you edit the documentation sources, you will need