clash-prelude-1.6.0: benchmarks/BenchRAM.hs
{-# LANGUAGE MagicHash, TypeApplications, DataKinds #-}
module BenchRAM (ramBench) where
import Criterion (Benchmark, env, bench, nf, bgroup, envWithCleanup)
import System.Directory
import System.IO
import Clash.Explicit.BlockRam
import Clash.Explicit.BlockRam.File
import Clash.Explicit.RAM
import Clash.Explicit.ROM
import Clash.Explicit.Signal
import Clash.Prelude.ROM
import Clash.Promoted.Nat
import Clash.Promoted.Nat.Literals
import qualified Clash.Sized.Vector as V
import Clash.Sized.Internal.BitVector (undefined#)
ramBench :: Benchmark
ramBench = bgroup "RAMs"
[ asyncRamBench
, asyncRomBench
, blockRamBench
, blockRamROBench
, blockRamFileBench
, blockRamFileROBench
, romBench
]
asyncRamBench :: Benchmark
asyncRamBench = env setup $ \m ->
bench "asyncRam#" $
nf (take 298 . drop 2 . simulate_lazy
(\rw -> let (r,w) = unbundle rw
in asyncRam# @System
clockGen
clockGen
enableGen
(SNat @4096)
r
(pure True)
w
w
)) m
where
setup = pure (zip [556,557..856] [557,558..857])
asyncRomBench :: Benchmark
asyncRomBench = env setup $ \m ->
bench "asyncRom#" $
nf (take 98 . drop 2 . fmap (asyncRom# ramInit)) m
where
ramInit = V.replicate d1024 (1 :: Int)
setup = pure ([557,558..857])
blockRamBench :: Benchmark
blockRamBench = env setup $ \m ->
bench "blockRam# (100% writes)" $
nf (take 8298 . drop 2 . simulate_lazy
(\w -> ram w
(pure True)
w
w
)) (cycle m)
where
ramInit = V.replicate (SNat @4096) (1 :: Int)
setup = pure ([557,558..857])
ram = blockRam# @System
clockGen
enableGen
ramInit
blockRamROBench :: Benchmark
blockRamROBench = env setup $ \m ->
bench "blockRam# (0% writes)" $
nf (take 8298 . drop 2 . simulate_lazy
(\w -> ram w
(pure False)
w
w
)) (cycle m)
where
ramInit = V.replicate (SNat @4096) (1 :: Int)
setup = pure ([557,558..857])
ram = blockRam# @System
clockGen
enableGen
ramInit
blockRamFileBench :: Benchmark
blockRamFileBench = envWithCleanup setup cleanup $ \(~(m,_,ram)) ->
bench "blockRamFile# (100% writes)" $
nf (take 8298 . drop 2 . simulate_lazy
(\w -> ram w
(pure True)
w
(pure undefined#)
)) (cycle m)
where
setup = do
(fp,h) <- openTempFile "." "mem.bin"
hPutStr h (unlines (replicate 4096 (replicate 63 '0' ++ ['1'])))
hClose h
let ram = blockRamFile# @64 @System
clockGen
enableGen
(SNat @4096)
fp
fp `seq` ram `seq` return ([557,558..857],fp,ram)
cleanup (_,f,_) = removeFile f
blockRamFileROBench :: Benchmark
blockRamFileROBench = envWithCleanup setup cleanup $ \(~(m,_,ram)) ->
bench "blockRamFile# (0% writes)" $
nf (take 8298 . drop 2 . simulate_lazy
(\w -> ram w
(pure False)
w
(pure undefined#)
)) (cycle m)
where
setup = do
(fp,h) <- openTempFile "." "mem.bin"
hPutStr h (unlines (replicate 4096 (replicate 63 '0' ++ ['1'])))
hClose h
let ram = blockRamFile# @64 @System
clockGen
enableGen
(SNat @4096)
fp
fp `seq` ram `seq` return ([557,558..857], fp, ram)
cleanup (_,f,_) = removeFile f
romBench :: Benchmark
romBench = env setup $ \m ->
bench "rom#" $
nf (take 98 . drop 2 . simulate_lazy
(\r -> rom# @System
clockGen
enableGen
ramInit
r
)) m
where
ramInit = V.replicate d1024 (1 :: Int)
setup = pure ([557,558..857])