summaryrefslogtreecommitdiffhomepage
path: root/ExpensiveHash.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-08-30 12:24:41 -0400
committerJoey Hess <joeyh@joeyh.name>2016-08-30 12:24:41 -0400
commit9363b4ba80de07c78805360bacf4c10b7efae13b (patch)
tree10c671b19365e161abec14d60ca0f751d3bd6f6a /ExpensiveHash.hs
parent125c49c73de4178ca6093ac526f769d6015dd6b3 (diff)
downloadkeysafe-9363b4ba80de07c78805360bacf4c10b7efae13b.tar.gz
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.
Diffstat (limited to 'ExpensiveHash.hs')
-rw-r--r--ExpensiveHash.hs14
1 files changed, 10 insertions, 4 deletions
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)