小编Sal*_*Sal的帖子

为union结构编写可存储的向量定义时的优化建议

我为下面的数据类型写了一个可存储的矢量实例(原始问题在这里):

data Atoms = I GHC.Int.Int32 | S GHC.Int.Int16
Run Code Online (Sandbox Code Playgroud)

用于为可存储矢量定义这些实例的代码如下.虽然我使用下面的代码获得了非常好的性能,但我对通用建议非常感兴趣,以提高该可存储实例的性能.通用建议,我的意思是:

  • 它不是GHC编译器版本特有的.您可以假设GHC 6.12.3+排除性能错误(如果早期版本中存在任何错误,并且与此处的代码相关).
  • 特定于平台的建议是可以的.您可以假设x86_64 Linux平台.
  • 与利用特定于硬件的优化的建议相比,更多以算法改进(大O)形式的通用建议非常受重视.但是,考虑到像偷看/捅这样的基本操作,据我所知,算法改进的空间不大(因此它更有价值,因为它是一种稀缺的商品:)
  • x86_64的编译器标志是可接受的(例如,告诉编译器有关删除浮点安全检查等).我使用"-O2 --make"选项来编译代码.

如果有任何已知的好的库源代码做类似的事情(即,为union/recursive数据类型定义可存储的实例),我将非常感兴趣检查它们.

import Data.Vector.Storable
import qualified Data.Vector.Storable as V
import Foreign
import Foreign.C.Types
import GHC.Int

data Atoms = I GHC.Int.Int32 | S GHC.Int.Int16
                deriving (Show)

instance Storable Atoms where
  sizeOf _ = 1 + sizeOf (undefined :: Int32)
  alignment _ = 1 + alignment (undefined :: Int32)

  {-# INLINE peek #-}
  peek p = do
            let p1 = (castPtr p::Ptr Word8) `plusPtr` …
Run Code Online (Sandbox Code Playgroud)

optimization haskell vector storable

5
推荐指数
1
解决办法
642
查看次数

在四个元组的向量中取消装箱盒装值

我试图调试性能问题作为更复杂的代码的一部分.似乎append我用来创建动态的,可增长的向量的(Int,Int,Int,Int)函数导致Int元组中的一个在被写入向量之前被装箱和取消装箱.我写了一个更简单的代码来重现这个问题 - 它似乎只有在我在append函数中添加向量增长功能时才会发生- 下面的示例代码(除了重现问题之外它没有做太多有用的工作),其后的片段core显示了值被装箱和取消装箱:

{-# LANGUAGE BangPatterns #-}
module Test
where
import Data.Vector.Unboxed.Mutable as MU
import Data.Vector.Unboxed as U hiding (mapM_)
import Control.Monad.ST as ST
import Control.Monad.Primitive (PrimState)
import Control.Monad (when)
import GHC.Float.RealFracMethods (int2Float)
import Data.STRef (newSTRef, writeSTRef, readSTRef)
import Data.Word

type MVI1 s  = MVector (PrimState (ST s)) Int
type MVI4 s  = MVector (PrimState (ST s)) (Int,Int,Int,Int)
data Snakev s = S {-# UNPACK #-}!Int
                                !(MVI4 s)

newVI1 …
Run Code Online (Sandbox Code Playgroud)

performance unboxing haskell vector ghc

5
推荐指数
1
解决办法
297
查看次数

在未装箱的向量中没有与unsafeUpdate_的流融合

当处理vectorif unsafeUpdate_函数用于更新某些元素时,是否可以保持流融合vector?答案在我做的测试中似乎没有.对于下面的代码,临时向量在upd函数中生成,如核心中所确认:

module Main where
import Data.Vector.Unboxed as U

upd :: Vector Int -> Vector Int
upd v = U.unsafeUpdate_ v (U.fromList [0]) (U.fromList [2])

sum :: Vector Int -> Int
sum = U.sum . upd

main = print $ Main.sum $ U.fromList [1..3]
Run Code Online (Sandbox Code Playgroud)

在核心中,$wupd函数被用于sum- 如下所示,它生成新的bytearray:

$wupd :: Vector Int -> Vector Int
$wupd =
  \ (w :: Vector Int) ->
    case w `cast` ... of _ …
Run Code Online (Sandbox Code Playgroud)

haskell vector fusion stream

5
推荐指数
1
解决办法
295
查看次数

在runST函数中传递范围状态

我有一个像下面的测试函数,用于runST内部变异状态.我go在其中定义了另一个函数,它返回Int包含在ST结果中(只是玩一些ST概念).问题是我的函数类型签名似乎是错误的.如果我注释掉函数类型签名,代码运行正常.使用注释代码中的类型签名,它不会编译,因为编译器将go函数的状态解释为与封闭范围中的状态不同.我将理解如何定义函数类型签名以将外部函数传递ST sgo函数的指针.

{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Word(Word32)
import Data.Vector.Unboxed as U hiding (mapM_,create)
import Control.Monad.ST as ST
import Control.Monad.Primitive (PrimState)
import System.Random.MWC

test :: Word32 -> Int
test x = runST $ do
     gen <- initialize (U.singleton $ fromIntegral x :: U.Vector Word32) :: (forall s. ST s (Gen (PrimState (ST s))))
     let --go :: Int -> ST s Int …
Run Code Online (Sandbox Code Playgroud)

haskell st

5
推荐指数
1
解决办法
160
查看次数

使用新成员覆盖类实例

假设我有一个简单的类AClass,其公共成员f1可以被覆盖.有什么方法可以定义AClass与另一个成员的新实例,f2AClass不是复制源代码?玩具代码如下:

class AClass a where
    f1 :: a -> Int

data Val = I Int

instance AClass Val where
  f1 x = 0

  -- the method below can't be added as it is not public member of AClass
  -- f2:: a -> Float
  -- f2 x = 0.0 
Run Code Online (Sandbox Code Playgroud)

我环顾四周,但没有找到任何关于如何做到这一点的明确例子(即我能理解的例子 - 清晰度是相对的).有什么可能的方法?关闭,新类型声明或其他什么?用上面的玩具代码演示技术会很有帮助 - 你可以改变data声明等(例如,用一个newtype包装器替换它Int),但上面代码中唯一不可变的是类声明AClass.这是因为假设该类已经由库编写者编写,因此,我无法触及它.最终结果应该是另一个继承了好东西的玩具代码AClass,并添加了f2成员.

当然,在这样的重写课程中会有一些警告.但是,它有助于了解什么是可能的,以及如何.

- 更新 -

下面的工作代码 …

haskell typeclass

3
推荐指数
2
解决办法
787
查看次数

从可存储的 MVector 构造 IOVector

你是如何构建IOVectorMVectorIOVector记录为:

type IOVector = MVector RealWorld
Run Code Online (Sandbox Code Playgroud)

我有一个像下面这样的 MVector,并且想要构建 IOVector(用于输入到 MSV.unsafeWith 函数 - MSV 是 Data.Vector.Storable.Mutable 库的简写):

v <- MSV.replicate 5 0 :: (IO (MVector (PrimState IO) CShort)) 
Run Code Online (Sandbox Code Playgroud)

haskell vector

3
推荐指数
1
解决办法
228
查看次数

为类型匹配定义Storable的受限子集

我收到下面的代码错误 - 我怀疑它与dispatch函数的类型签名有关,它返回一个Vector类型Storable a.有什么简单的方法来更新dispatch功能类型签名只做Int32CChar在签名类型:

{-#  LANGUAGE BangPatterns #-}
import Data.Vector.Storable as SV
import Foreign.C.Types (CChar)
import GHC.Int (Int32)

data AList = I {-# UNPACK #-} !(SV.Vector Int32)
              | S {-# UNPACK #-} !(SV.Vector CChar)


dispatch :: (Storable a) => AList -> SV.Vector a
dispatch (I x) = x
dispatch (S x) = x
Run Code Online (Sandbox Code Playgroud)

ghci 7.4.1中的错误:

    test.hs:11:18:
    Couldn't match type `CChar' with `Int32'
    Expected type: Vector a
      Actual type: …
Run Code Online (Sandbox Code Playgroud)

haskell

3
推荐指数
1
解决办法
115
查看次数

从forall量化中扣除等级

鉴于下面的代码(来自Yoneda Lemma解释):

{-# LANGUAGE RankNTypes #-}

check1 :: a -> (forall b . (a -> b) -> b)
check1 a f = f a

uncheck1 :: (forall b . (a -> b) -> b) -> a
uncheck1 t = t id
Run Code Online (Sandbox Code Playgroud)

forall量化check1似乎在以下rank-1方面得到证实ghci:

$ :t check1
check1 :: a -> (a -> b) -> b
$ :t uncheck1
uncheck1 :: (forall b. (a -> b) -> b) -> a
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么check1有 …

haskell

3
推荐指数
1
解决办法
122
查看次数

检索通用SOP中的记录功能

Sum of Products方法中,如何检索记录功能?下面带有record datatype(ghc 7.10.3)的示例代码:

{-# LANGUAGE DeriveGeneric #-}
import qualified GHC.Generics as GHC
import Generics.SOP
data Rec = Rec { frec :: Int, srec :: Maybe String}
  deriving (Show, GHC.Generic)

instance Generic Rec     -- empty
instance HasDatatypeInfo Rec
Run Code Online (Sandbox Code Playgroud)

让我们看看DataTypeInfo ghci提示:

*Main> datatypeInfo (Proxy :: Proxy Rec)
ADT "Main" "Rec" (Record "Rec" (FieldInfo "frec" :* (FieldInfo "srec" :* Nil)) :* Nil)
Run Code Online (Sandbox Code Playgroud)

我们看到frec并且srec都是FieldInfo具有FieldInfofieldName字符串的构造函数的类型.所以,我没有看到任何方法来获得实际的功能frec :: Rec …

haskell ghc-generics

3
推荐指数
1
解决办法
188
查看次数

while循环中的错误

我无法弄清楚while我在下面写的玩具循环中的错误是什么.它适用于一个输入,但挂起其他输入.这是代码 - while循环采用向量,向量上的谓词和向量上的变换函数,并返回另一个向量:

import Data.Vector.Unboxed as U

while :: Vector Int -> (Vector Int -> Bool) -> (Vector Int -> Vector Int) -> Vector Int
while v p f = go 0 v
      where go n x = if (p x) then go (n+1) (f x)
                              else x

test :: Vector Int -> Vector Int
test a = while a (\x -> (x!0) < 2) (\x -> U.map (+1) a)

main = print $ test (U.fromList [0])
Run Code Online (Sandbox Code Playgroud)

这依赖于执行 …

haskell loops

2
推荐指数
1
解决办法
131
查看次数