From a3eee4ad50f102140a4dc3a99df9cbc69aa22f9b Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Fri, 17 Dec 2010 16:52:40 +0100 Subject: [PATCH] Parallelize the balancing computations 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 | 14 ++++++++++---- README | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Ganeti/HTools/Cluster.hs b/Ganeti/HTools/Cluster.hs index 8a79ff951..1e111f05c 100644 --- a/Ganeti/HTools/Cluster.hs +++ b/Ganeti/HTools/Cluster.hs @@ -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 62b9c1ac6..cb7f61185 100644 --- 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 -- GitLab