summaryrefslogtreecommitdiffhomepage
path: root/Cost.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-08-30 14:42:06 -0400
committerJoey Hess <joeyh@joeyh.name>2016-08-30 14:42:06 -0400
commitc273ac0173c9b277b2ba08a086e3091ba32d4319 (patch)
tree3cb1d60625b537f38e6194c1c80a8b119a9b0aaf /Cost.hs
parentfe975ad122c77b4936f3e28c868b056fdaf2f842 (diff)
downloadkeysafe-c273ac0173c9b277b2ba08a086e3091ba32d4319.tar.gz
Improve time estimates, taking into account the number of cores.
This only affects time estimates while keysafe is generating hashes; it does not affect cost estimates to brute-force.
Diffstat (limited to 'Cost.hs')
-rw-r--r--Cost.hs40
1 files changed, 30 insertions, 10 deletions
diff --git a/Cost.hs b/Cost.hs
index c8184c1..77c2c4c 100644
--- a/Cost.hs
+++ b/Cost.hs
@@ -11,29 +11,36 @@ module Cost (
) where
import Types.Cost
+import Data.List
+import Data.Maybe
+import Text.Read
-- | Cost in seconds, with the type of hardware needed.
totalCost :: Cost op -> (Seconds, [UsingHardware])
-totalCost (CPUCost s) = (s, [UsingCPU])
+totalCost (CPUCost s _) = (s, [UsingCPU])
raiseCostPower :: Cost c -> Entropy e -> Cost c
raiseCostPower c (Entropy e) = mapCost (* 2^e) c
mapCost :: (Integer -> Integer) -> Cost op -> Cost op
-mapCost f (CPUCost (Seconds n)) = CPUCost (Seconds (f n))
+mapCost f (CPUCost (Seconds n) d) = CPUCost (Seconds (f n)) d
-showCostMinutes :: Cost op -> String
-showCostMinutes (CPUCost (Seconds n))
- | n < 61 = "1 minute"
- | otherwise = show (n `div` 60) ++ " minutes"
+type NumCores = Integer
+
+showCostMinutes :: NumCores -> Cost op -> String
+showCostMinutes numcores (CPUCost (Seconds n) (Divisibility d))
+ | n' < 61 = "1 minute"
+ | otherwise = show (n' `div` 60) ++ " minutes"
+ where
+ n' = n `div` min numcores d
-- If an operation took n seconds on a number of cores,
--- multiple to get the CPUCost, which is for a single core.
-coreCost :: Integer -> Seconds -> Cost op
-coreCost cores (Seconds n) = CPUCost (Seconds (cores * n))
+-- multiply to get the CPUCost, which is for a single core.
+coreCost :: NumCores -> Seconds -> Divisibility -> Cost op
+coreCost cores (Seconds n) d = CPUCost (Seconds (cores * n)) d
castCost :: Cost a -> Cost b
-castCost (CPUCost s) = CPUCost s
+castCost (CPUCost s d) = CPUCost s d
-- | CostCalc for a brute force linear search through an entropy space
-- in which each step entails paying a cost.
@@ -127,3 +134,16 @@ costOverTimeTable cost thisyear = go [] thisyear $ costOverTime cost thisyear
in if yprev < y - 1
then go (s:" ...":t) y ys
else go (s:t) y ys
+
+-- Number of physical cores. This is not the same as
+-- getNumProcessors, which includes hyper-threading.
+getNumCores :: IO (Maybe NumCores)
+getNumCores = getmax . mapMaybe parse . lines <$> readFile "/proc/cpuinfo"
+ where
+ getmax [] = Nothing
+ getmax l = Just $
+ maximum l + 1 -- add 1 because /proc/cpuinfo counts from 0
+ parse l
+ | "core id" `isPrefixOf` l =
+ readMaybe $ drop 1 $ dropWhile (/= ':') l
+ | otherwise = Nothing