【问题标题】:How much impact does branch prediction have on Haskell program?分支预测对 Haskell 程序有多大影响?
【发布时间】:2019-08-20 22:53:43
【问题描述】:

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

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

【问题讨论】:

  • 你是如何编译和测试你的代码的?
  • @MarcTalbot 如果有帮助,我已经在我的 .cabal 配置中进行了编辑。
  • 所以你正在构建为未优化的代码?
  • @MarcTalbot 我认为 GHC 默认会进行优化?我确实尝试过-O0,但它并没有改变任何东西。甚至不是排序的速度。
  • GHC 默认不做优化。 -O0 表示“不做优化”,是默认值。 -O2 是第一个尝试启用优化的标志。

标签: haskell cpu branch-prediction


【解决方案1】:

在(假定为)递归案例中,您调用了 sort 而不是 insertionSort。这是一个运行优化的合并排序,它在 O(n) 时间内处理反向输入。因此,您的“最坏情况”实际上是所写算法的近乎最佳情况,而不是预期的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-01
    • 2023-03-12
    • 2020-02-12
    • 2017-01-26
    • 2020-07-16
    • 2018-07-29
    • 2015-08-12
    • 2021-07-23
    相关资源
    最近更新 更多