vincenthz/hs-cpu — pull request #4 by pxqr (2013-10-02 03:13:18+00:00)
Title: Use gcc intrinsics instead of handwritten byte swap functions

Hi, Vincent.

`bits-extras` package already provides [byteSwap][byteSwap] function which is implemented through gcc builtins, so there is no need in handwritten cbits functions for byte swapping. It's also three times faster, since it uses unsafe foreign import.

[byteSwap]: http://hackage.haskell.org/package/bits-extras-0.1.3/docs/Data-Bits-Extras.html#v:byteSwap

A simple bench:

```haskell
module Main (main) where

import Criterion.Main
import Data.Bits.Extras
import Data.Word
import System.Endian

cycleFn :: Int -> (a -> a) -> (a -> a)
cycleFn n = foldr (.) id . replicate n

toBE64' :: Word64 -> Word64
toBE64' = if getSystemEndianness == BigEndian then id else byteSwap
{-# INLINE toBE64' #-}

toBE32' :: Word32 -> Word32
toBE32' = if getSystemEndianness == BigEndian then id else byteSwap
{-# INLINE toBE32' #-}

main :: IO ()
main = defaultMain
[ bench "toBE64/bit-extras" $ nf (cycleFn 1000 toBE64') 0
, bench "toBE64/cpu" $ nf (cycleFn 1000 toBE64 ) 0
, bench "toBE32/bit-extras" $ nf (cycleFn 1000 toBE32') 0
, bench "toBE32/cpu" $ nf (cycleFn 1000 toBE32 ) 0
]
```

result:

```
warming up
estimating clock resolution...
mean is 2.770140 us (320001 iterations)
found 2381 outliers among 319999 samples (0.7%)
2191 (0.7%) high severe
estimating cost of a clock call...
mean is 938.0674 ns (15 iterations)
found 2 outliers among 15 samples (13.3%)
2 (13.3%) high severe

benchmarking toBE64/bit-extras
mean: 33.49609 us, lb 33.42051 us, ub 33.60897 us, ci 0.950
std dev: 468.2486 ns, lb 346.7306 ns, ub 669.7235 ns, ci 0.950
found 10 outliers among 100 samples (10.0%)
4 (4.0%) high mild
6 (6.0%) high severe
variance introduced by outliers: 6.608%
variance is slightly inflated by outliers

benchmarking toBE64/cpu
mean: 100.4672 us, lb 100.2891 us, ub 100.8130 us, ci 0.950
std dev: 1.230920 us, lb 753.7591 ns, ub 2.305255 us, ci 0.950

benchmarking toBE32/bit-extras
mean: 33.58718 us, lb 33.49422 us, ub 33.72801 us, ci 0.950
std dev: 578.5219 ns, lb 419.2628 ns, ub 789.5771 ns, ci 0.950
found 8 outliers among 100 samples (8.0%)
2 (2.0%) high mild
6 (6.0%) high severe
variance introduced by outliers: 10.363%
variance is moderately inflated by outliers

benchmarking toBE32/cpu
mean: 102.4942 us, lb 102.1378 us, ub 102.9871 us, ci 0.950
std dev: 2.119861 us, lb 1.669219 us, ub 2.753717 us, ci 0.950
found 17 outliers among 100 samples (17.0%)
5 (5.0%) high mild
12 (12.0%) high severe
variance introduced by outliers: 13.284%
variance is moderately inflated by outliers
```