From 9363b4ba80de07c78805360bacf4c10b7efae13b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 30 Aug 2016 12:24:41 -0400 Subject: adjust benchmark expected time based on the host's number of cores The goal of benchmarking the expensive hash is to get an accurate time estimate for a single CPU, but argon2 uses 4 threads, so on a machine with 4 cores, it should only take a quarter as long. --- ExpensiveHash.hs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'ExpensiveHash.hs') diff --git a/ExpensiveHash.hs b/ExpensiveHash.hs index f9a9548..4031ef3 100644 --- a/ExpensiveHash.hs +++ b/ExpensiveHash.hs @@ -19,6 +19,7 @@ import Data.Time.Clock import Control.DeepSeq import Control.Monad import Data.Monoid +import GHC.Conc (getNumProcessors) -- | A hash that is expensive to calculate. -- @@ -46,7 +47,7 @@ expensiveHash (UseArgon2 cost opts) (Salt s) b = ExpensiveHash cost $ in sb <> B.replicate (8 - B.length sb ) 32 benchmarkExpensiveHash :: Int -> ExpensiveHashTunable -> Cost op -> IO (BenchmarkResult (Cost op)) -benchmarkExpensiveHash rounds tunables expected = do +benchmarkExpensiveHash rounds tunables@(UseArgon2 _ hashopts) expected = do start <- getCurrentTime forM_ [1..rounds] $ \_ -> do let ExpensiveHash _ t = expensiveHash tunables @@ -56,8 +57,15 @@ benchmarkExpensiveHash rounds tunables expected = do end <- getCurrentTime let diff = floor $ end `diffUTCTime` start let actual = CPUCost $ Seconds diff + -- The expected cost is for a single core, so adjust it + -- based on the number of cores, up to a maximum of the number + -- of threads that the hash is configred to use. + numcpus <- fromIntegral <$> getNumProcessors + let maxthreads = Argon2.hashParallelism hashopts + let usedcpus = if numcpus > maxthreads then maxthreads else numcpus + let adjustedexpected = mapCost (`div` fromIntegral usedcpus) expected return $ BenchmarkResult - { expectedBenchmark = expected + { expectedBenchmark = adjustedexpected , actualBenchmark = actual } @@ -65,8 +73,6 @@ benchmarkTunables :: Tunables -> IO () benchmarkTunables tunables = do putStrLn "/proc/cpuinfo:" putStrLn =<< readFile "/proc/cpuinfo" - putStrLn "Note that expected times are for 1 core machine." - putStrLn "If this machine has 2 cores, the actual times should be half the expected times." putStrLn "Benchmarking 16 rounds of key generation hash..." print =<< benchmarkExpensiveHash 16 (keyEncryptionKeyHash $ keyEncryptionKeyTunable tunables) -- cgit v1.2.3