summaryrefslogtreecommitdiff
path: root/compiler/ghci
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2016-02-01 16:39:50 +0000
committerSimon Marlow <marlowsd@gmail.com>2016-02-02 08:04:11 +0000
commitc996db5b1802ebeb93420785127f7fd55b7ec0c0 (patch)
tree9981205beac6f606ee152012e4135bce3a9a9c09 /compiler/ghci
parent7cb1fae2d6ec90b10708a2631cd1069561177bd4 (diff)
downloadhaskell-c996db5b1802ebeb93420785127f7fd55b7ec0c0.tar.gz
Remote GHCi: parallelise BCO serialization
Summary: Serialization of BCOs is slow, but we can parallelise it when using ghci -j<n>. It parallelises nicely, saving multiple seconds off the link time in a large example I have. Test Plan: * validate * `ghci -fexternal-interpreter` in `nofib/real/anna` Reviewers: niteria, bgamari, ezyang, austin, hvr, erikd Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1877 GHC Trac Issues: #11100
Diffstat (limited to 'compiler/ghci')
-rw-r--r--compiler/ghci/GHCi.hs39
-rw-r--r--compiler/ghci/Linker.hs4
2 files changed, 40 insertions, 3 deletions
diff --git a/compiler/ghci/GHCi.hs b/compiler/ghci/GHCi.hs
index 2e2cd35686..80aeccf505 100644
--- a/compiler/ghci/GHCi.hs
+++ b/compiler/ghci/GHCi.hs
@@ -13,6 +13,7 @@ module GHCi
, evalString
, evalStringToIOString
, mallocData
+ , createBCOs
, mkCostCentres
, costCentreStackInfo
, newBreakArray
@@ -47,6 +48,7 @@ module GHCi
import GHCi.Message
import GHCi.Run
import GHCi.RemoteTypes
+import GHCi.ResolvedBCO
import GHCi.BreakArray (BreakArray)
import HscTypes
import UniqFM
@@ -57,14 +59,17 @@ import Outputable
import Exception
import BasicTypes
import FastString
+import Util
import Control.Concurrent
import Control.Monad
import Control.Monad.IO.Class
import Data.Binary
+import Data.Binary.Put
import Data.ByteString (ByteString)
+import qualified Data.ByteString.Lazy as LB
import Data.IORef
-import Foreign
+import Foreign hiding (void)
import GHC.Stack.CCS (CostCentre,CostCentreStack)
import System.Exit
import Data.Maybe
@@ -76,6 +81,7 @@ import GHC.IO.Handle.FD (fdToHandle)
import System.Posix as Posix
#endif
import System.Process
+import GHC.Conc
{- Note [Remote GHCi]
@@ -258,6 +264,37 @@ mkCostCentres
mkCostCentres hsc_env mod ccs =
iservCmd hsc_env (MkCostCentres mod ccs)
+-- | Create a set of BCOs that may be mutually recursive.
+createBCOs :: HscEnv -> [ResolvedBCO] -> IO [HValueRef]
+createBCOs hsc_env rbcos = do
+ n_jobs <- case parMakeCount (hsc_dflags hsc_env) of
+ Nothing -> liftIO getNumProcessors
+ Just n -> return n
+ -- Serializing ResolvedBCO is expensive, so if we're in parallel mode
+ -- (-j<n>) parallelise the serialization.
+ if (n_jobs == 1)
+ then
+ iservCmd hsc_env (CreateBCOs [runPut (put rbcos)])
+
+ else do
+ old_caps <- getNumCapabilities
+ if old_caps == n_jobs
+ then void $ evaluate puts
+ else bracket_ (setNumCapabilities n_jobs)
+ (setNumCapabilities old_caps)
+ (void $ evaluate puts)
+ iservCmd hsc_env (CreateBCOs puts)
+ where
+ puts = parMap doChunk (chunkList 100 rbcos)
+
+ -- make sure we force the whole lazy ByteString
+ doChunk c = pseq (LB.length bs) bs
+ where bs = runPut (put c)
+
+ -- We don't have the parallel package, so roll our own simple parMap
+ parMap _ [] = []
+ parMap f (x:xs) = fx `par` (fxs `pseq` (fx : fxs))
+ where fx = f x; fxs = parMap f xs
costCentreStackInfo :: HscEnv -> RemotePtr CostCentreStack -> IO [String]
costCentreStackInfo hsc_env ccs =
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs
index 982b4fc148..2b471ee0ee 100644
--- a/compiler/ghci/Linker.hs
+++ b/compiler/ghci/Linker.hs
@@ -499,7 +499,7 @@ linkExpr hsc_env span root_ul_bco
; let nobreakarray = error "no break array"
bco_ix = mkNameEnv [(unlinkedBCOName root_ul_bco, 0)]
; resolved <- linkBCO hsc_env ie ce bco_ix nobreakarray root_ul_bco
- ; [root_hvref] <- iservCmd hsc_env (CreateBCOs [resolved])
+ ; [root_hvref] <- createBCOs hsc_env [resolved]
; fhv <- mkFinalizedHValue hsc_env root_hvref
; return (pls, fhv)
}}}
@@ -971,7 +971,7 @@ linkSomeBCOs hsc_env ie ce mods = foldr fun do_link mods []
bco_ix = mkNameEnv (zip names [0..])
resolved <- sequence [ linkBCO hsc_env ie ce bco_ix breakarray bco
| (breakarray, bco) <- flat ]
- hvrefs <- iservCmd hsc_env (CreateBCOs resolved)
+ hvrefs <- createBCOs hsc_env resolved
return (zip names hvrefs)
-- | Useful to apply to the result of 'linkSomeBCOs'