Skip to content

Instantly share code, notes, and snippets.

@thumphries
Created August 24, 2017 05:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save thumphries/524e5513620287a4105cc3e20357b41d to your computer and use it in GitHub Desktop.
Save thumphries/524e5513620287a4105cc3e20357b41d to your computer and use it in GitHub Desktop.
Demonstration of SIMD performance gap
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B8
import Criterion.Main
import Criterion.Types (Config (..))
import qualified Mystery
input :: Int -> ByteString
input x =
B8.replicate x 'Z'
main :: IO ()
main = do
let cfg = defaultConfig {
reportFile = Just "bench.html"
, csvFile = Just "bench.csv"
}
bmN = nf Mystery.toLowerNative . input
bmF = nf Mystery.toLowerFFI . input
defaultMainWith cfg [
bgroup "toLowerNative" [
bench "100" $ bmN 100
, bench "500" $ bmN 500
, bench "1000" $ bmN 1000
, bench "2000" $ bmN 2000
]
, bgroup "toLowerFFI" [
bench "100" $ bmF 100
, bench "500" $ bmF 500
, bench "1000" $ bmF 1000
, bench "2000" $ bmF 2000
]
]
void to_lower (char* str, int len) {
for (int i = 0; i < len; i++) {
str[i] |= 0x20;
};
};
name: mystery
version: 0.1.0.0
synopsis: A performance murder mystery
author: Tim Humphries
maintainer: tim@utf8.me
build-type: Simple
cabal-version: >=1.10
library
default-language: Haskell2010
ghc-options: -Wall
build-depends:
base >= 4.9 && < 4.11
, bytestring >= 0.10.8 && < 0.11
c-sources: lower.c
exposed-modules:
Mystery
benchmark bench
type: exitcode-stdio-1.0
main-is: Bench.hs
ghc-options: -Wall -threaded -O2
build-depends: base
, mystery
, bytestring
, criterion
{-# LANGUAGE ForeignFunctionInterface #-}
module Mystery where
import Data.Bits ((.|.))
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Foreign.C.Types (CChar)
import Foreign.Ptr (Ptr)
import qualified System.IO.Unsafe as Unsafe
toLowerNative :: ByteString -> ByteString
toLowerNative =
B.map (.|. 0x20)
toLowerFFI :: ByteString -> ByteString
toLowerFFI bs =
Unsafe.unsafePerformIO . B.useAsCStringLen bs $ \(ptr, len) -> do
to_lower ptr len
B.packCStringLen (ptr, len)
foreign import ccall to_lower :: Ptr CChar -> Int -> IO ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment