分支预测对Haskell程序有多大影响?

时间:2019-03-30 00:06:56

标签: haskell cpu branch-prediction

我正在对最坏情况的输入(反向顺序列表)和随机输入进行基准插入排序。

import Control.Monad
import Data.List
import System.Random
import Control.Exception
import Control.DeepSeq
import Criterion.Main

--- Sorting ---
insertionSort :: (Ord a) => [a] -> [a]
insertionSort [] = []
insertionSort (x:xs) = x `insert` (sort xs)

--- Generators ---
worstCaseGen :: Int -> [Int]
worstCaseGen n = [n, n-1..1]

bestCaseGen :: Int -> [Int]
bestCaseGen n = [1..n]

randomGen :: Int -> StdGen -> [Int]
randomGen n = take n . randoms

--- Testing ---
main = do
  gen <- newStdGen
  randomList <- evaluate $ force $ randomGen 10000 gen
  defaultMain [
    bgroup "Insertion Sort" [ bench "worst" $ nf insertionSort (worstCaseGen 10000)
                            , bench "best" $ nf insertionSort (bestCaseGen 10000)
                            , bench "gen" $ nf last randomList
                            , bench "random" $ nf insertionSort randomList
                            ]
    ]

尽管随机输入的性能应与最差情况输入的性能大致相同,但实际上基准测试表明其速度要慢20倍左右。我的猜测是分支预测开始,随机情况很难预测,因此变慢了。这是真的吗?

如果有帮助,这是我的.cabal:

executable BranchPrediction
  main-is:             Main.hs
  build-depends:       base >=4.12 && <4.13,
                       random,
                       criterion ==1.5.4.0,
                       deepseq ==1.4.4.0
  default-language:    Haskell2010

1 个答案:

答案 0 :(得分:6)

在您的(假设是)递归案例中,您致电sort而不是insertionSort。这是运行优化的合并排序,可以处理O(n)时间的反向输入。因此,您所写的“最坏情况”实际上是该算法的最佳情况,而不是预期的情况。