{-# LANGUAGE ScopedTypeVariables #-} import Control.Monad.Primitive import Control.Monad import Foreign.C.Types import Foreign.Ptr import Unsafe.Coerce import Data.Complex import qualified Data.Vector.Generic as VG import qualified Data.Vector.Generic.Mutable as VGM import qualified Data.Vector.Storable as VS import qualified Data.Vector.Storable.Mutable as VSM import qualified Data.Vector.Fusion.Bundle as VFS import qualified Data.Vector.Fusion.Stream.Monadic as VFSM import Foreign.Storable.Complex import Criterion.Main import SDR.FilterInternal import SDR.Util import SDR.CPUID theBench :: IO () theBench = do --Setup let size = 16384 numCoeffs = 128 num = size - numCoeffs + 1 decimation = 4 interpolation = 3 numCoeffsDiv2 = 64 coeffsList :: [Float] coeffsList = take numCoeffs [0 ..] coeffs :: VS.Vector Float coeffs = VG.fromList $ take numCoeffs [0 ..] coeffsSym :: VS.Vector Float coeffsSym = VG.fromList $ take numCoeffsDiv2 [0 ..] inBuf :: VS.Vector Float inBuf = VG.fromList $ take size [0 ..] inBufComplex :: VS.Vector (Complex Float) inBufComplex = VG.fromList $ take size $ do i <- [0..] return $ i :+ i inBufRTLSDR :: VS.Vector CUChar inBufRTLSDR = VG.fromList $ take size [0 ..] inBufBladeRF :: VS.Vector CShort inBufBladeRF = VG.fromList $ take size [0 ..] numConv = 16386 inBufConv :: VS.Vector CUChar inBufConv = VG.fromList $ take size $ concat $ repeat [0 .. 255] duplicate :: [a] -> [a] duplicate = concatMap func where func x = [x, x] coeffs2 :: VS.Vector Float coeffs2 = VG.fromList $ duplicate $ take numCoeffs [0 ..] outBuf :: VS.MVector RealWorld Float <- VGM.new size outBufComplex :: VS.MVector RealWorld (Complex Float) <- VGM.new size info <- getCPUInfo let hasFeatures :: [(CPUInfo -> Bool, a)] -> [a] hasFeatures = map snd . filter (($ info) . fst) resampler3 <- resampleCRR2 interpolation decimation coeffsList resampler4 <- resampleCSSERR interpolation decimation coeffsList resampler5 <- resampleCAVXRR interpolation decimation coeffsList resampler3C <- resampleCRC interpolation decimation coeffsList resampler4C <- resampleCSSERC interpolation decimation coeffsList resampler5C <- resampleCAVXRC interpolation decimation coeffsList --Benchmarks defaultMain [ bgroup "filter" [ bgroup "real" $ hasFeatures [ (const True, bench "highLevel" $ nfIO $ filterHighLevel coeffs num inBuf outBuf), (const True, bench "imperative1" $ nfIO $ filterImperative1 coeffs num inBuf outBuf), (const True, bench "imperative2" $ nfIO $ filterImperative2 coeffs num inBuf outBuf), (const True, bench "c" $ nfIO $ filterCRR coeffs num inBuf outBuf), (hasSSE42, bench "cSSE" $ nfIO $ filterCSSERR coeffs num inBuf outBuf), (hasSSE42, bench "cSSESym" $ nfIO $ filterCSSESymmetricRR coeffsSym num inBuf outBuf), (hasAVX, bench "cAVX" $ nfIO $ filterCAVXRR coeffs num inBuf outBuf), (hasAVX, bench "cAVXSym" $ nfIO $ filterCAVXSymmetricRR coeffsSym num inBuf outBuf) ], bgroup "complex" $ hasFeatures [ (const True, bench "highLevel" $ nfIO $ filterHighLevel coeffs num inBufComplex outBufComplex), (const True, bench "c" $ nfIO $ filterCRC coeffs num inBufComplex outBufComplex), (hasSSE42, bench "cSSE" $ nfIO $ filterCSSERC coeffs2 num inBufComplex outBufComplex), (hasSSE42, bench "cSSE2" $ nfIO $ filterCSSERC2 coeffs num inBufComplex outBufComplex), (hasSSE42, bench "cSSESym" $ nfIO $ filterCSSESymmetricRC coeffsSym num inBufComplex outBufComplex), (hasAVX, bench "cAVX" $ nfIO $ filterCAVXRC coeffs2 num inBufComplex outBufComplex), (hasAVX, bench "cAVX2" $ nfIO $ filterCAVXRC2 coeffs num inBufComplex outBufComplex), (hasAVX, bench "cAVXSym" $ nfIO $ filterCAVXSymmetricRC coeffsSym num inBufComplex outBufComplex) ] ], bgroup "decimate" [ bgroup "real" $ hasFeatures [ (const True, bench "highLevel" $ nfIO $ decimateHighLevel decimation coeffs (num `quot` decimation) inBuf outBuf), (const True, bench "c" $ nfIO $ decimateCRR decimation coeffs (num `quot` decimation) inBuf outBuf), (hasSSE42, bench "cSSE" $ nfIO $ decimateCSSERR decimation coeffs (num `quot` decimation) inBuf outBuf), (hasSSE42, bench "cSSESym" $ nfIO $ decimateCSSESymmetricRR decimation coeffsSym (num `quot` decimation) inBuf outBuf), (hasAVX, bench "cAVX" $ nfIO $ decimateCAVXRR decimation coeffs (num `quot` decimation) inBuf outBuf), (hasAVX, bench "cAVXSym" $ nfIO $ decimateCAVXSymmetricRR decimation coeffsSym (num `quot` decimation) inBuf outBuf) ], bgroup "complex" $ hasFeatures [ (const True, bench "highLevel" $ nfIO $ decimateHighLevel decimation coeffs (num `quot` decimation) inBufComplex outBufComplex), (const True, bench "c" $ nfIO $ decimateCRC decimation coeffs (num `quot` decimation) inBufComplex outBufComplex), (hasSSE42, bench "cSSE" $ nfIO $ decimateCSSERC decimation coeffs2 (num `quot` decimation) inBufComplex outBufComplex), (hasSSE42, bench "cSSE2" $ nfIO $ decimateCSSERC2 decimation coeffs (num `quot` decimation) inBufComplex outBufComplex), (hasSSE42, bench "cSSESym" $ nfIO $ decimateCSSESymmetricRC decimation coeffsSym (num `quot` decimation) inBufComplex outBufComplex), (hasAVX, bench "cAVX" $ nfIO $ decimateCAVXRC decimation coeffs2 (num `quot` decimation) inBufComplex outBufComplex), (hasAVX, bench "cAVX2" $ nfIO $ decimateCAVXRC2 decimation coeffs (num `quot` decimation) inBufComplex outBufComplex), (hasAVX, bench "cAVXSym" $ nfIO $ decimateCAVXSymmetricRC decimation coeffsSym (num `quot` decimation) inBufComplex outBufComplex) ] ], bgroup "resample" [ bgroup "real" $ hasFeatures [ (const True, bench "highLevel" $ nfIO $ resampleHighLevel interpolation decimation coeffs 0 (num `quot` decimation) inBuf outBuf), (const True, bench "c" $ nfIO $ resampleCRR (num `quot` decimation) interpolation decimation 0 coeffs inBuf outBuf), (const True, bench "c2" $ nfIO $ resampler3 (num `quot` decimation) 0 inBuf outBuf), (hasSSE42, bench "cSSE" $ nfIO $ resampler4 (num `quot` decimation) 0 inBuf outBuf), (hasAVX, bench "cAVX" $ nfIO $ resampler5 (num `quot` decimation) 0 inBuf outBuf) ], bgroup "complex" $ hasFeatures [ (const True, bench "highLevel" $ nfIO $ resampleHighLevel interpolation decimation coeffs 0 (num `quot` decimation) inBufComplex outBufComplex), (const True, bench "c" $ nfIO $ resampler3C (num `quot` decimation) 0 inBufComplex outBufComplex), (const True, bench "SSE" $ nfIO $ resampler4C (num `quot` decimation) 0 inBufComplex outBufComplex), (const True, bench "AVX" $ nfIO $ resampler5C (num `quot` decimation) 0 inBufComplex outBufComplex) ] ], bgroup "scaling" $ hasFeatures [ (const True, bench "c" $ nfIO $ scaleC 0.3 inBuf outBuf), (hasSSE42, bench "cSSE" $ nfIO $ scaleCSSE 0.3 inBuf outBuf), (hasAVX, bench "cAVX" $ nfIO $ scaleCAVX 0.3 inBuf outBuf) ], bgroup "conversion" [ bgroup "RTLSDR" $ hasFeatures [ (const True, bench "h" $ nf (interleavedIQUnsigned256ToFloat :: VS.Vector CUChar -> VS.Vector (Complex Float)) inBufRTLSDR), (const True, bench "c" $ nf interleavedIQUnsignedByteToFloat inBufRTLSDR), (hasSSE42, bench "cSSE" $ nf interleavedIQUnsignedByteToFloatSSE inBufRTLSDR), (hasAVX2, bench "cAVX" $ nf interleavedIQUnsignedByteToFloatAVX inBufRTLSDR) ], bgroup "BladeRF" $ hasFeatures [ (const True, bench "h" $ nf (interleavedIQSigned2048ToFloat :: VS.Vector CShort -> VS.Vector (Complex Float)) inBufBladeRF), (const True, bench "c" $ nf interleavedIQSignedWordToFloat inBufBladeRF), (hasSSE42, bench "cSSE" $ nf interleavedIQSignedWordToFloatSSE inBufBladeRF), (hasAVX2, bench "cAVX" $ nf interleavedIQSignedWordToFloatAVX inBufBladeRF) ] ] ] main = theBench