小编Sal*_*Sal的帖子

外国primop的cmm调用格式(integer-gmp示例)

我一直在检查integer-gmp源代码,以了解如何根据GHC Primops页面上记录的cmm实现外部primops .我知道使用llvm hack或fvia-C/gcc 实现它们的技术- 这对我来说是理解interger-gmp库使用的第三种方法的更多学习经验.

所以,我抬头一看CMM教程MSFT页(PDF链接),经历了GHC CMM页,仍然存在一些悬而未决的问题(很难保持在头所有这些概念没有挖掘到CMM这就是我现在所做的).这是来自integer-bmp cmm文件的代码片段:

integer_cmm_int2Integerzh (W_ val)
{
   W_ s, p; /* to avoid aliasing */

   ALLOC_PRIM_N (SIZEOF_StgArrWords + WDS(1), integer_cmm_int2Integerzh, val);

   p = Hp - SIZEOF_StgArrWords;
   SET_HDR(p, stg_ARR_WORDS_info, CCCS);
   StgArrWords_bytes(p) = SIZEOF_W;

   /* mpz_set_si is inlined here, makes things simpler */
   if (%lt(val,0)) {
        s  = -1;
        Hp(0) = -val;
   } else {
     if (%gt(val,0)) {
        s = 1;
        Hp(0) = val; …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

63
推荐指数
1
解决办法
991
查看次数

为ST monad编写有效的迭代循环

go worker tail-recursive loop pattern似乎非常适合编写纯代码.为STmonad 编写这种循环的等效方法是什么?更具体地说,我想避免循环迭代中的新堆分配.我的猜测是它涉及任一CPS transformationfixST重新写使得所有在跨越环路改变的值被在每个迭代中通过,从而使寄存器的位置(或在溢出的情况下,叠加)适用于在可迭代这些值的代码.我在下面有一个简化的示例(不要尝试运行它 - 它可能会因为分段错误而崩溃!),其中涉及一个findSnakes具有go工作模式的函数,但更改的状态值不通过累加器参数传递:

{-# 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 as CM (when,forM_)
import Data.Int

type MVI1 s  = MVector (PrimState (ST s)) Int

-- function to find previous y
findYP :: MVI1 s -> Int -> Int -> ST s Int
findYP fp …
Run Code Online (Sandbox Code Playgroud)

monads state haskell loops

16
推荐指数
1
解决办法
718
查看次数

生成ByteString(或任何具有ForeignPtr组件的对象)的函数的纯度

由于a ByteString是一个构造函数ForeignPtr:

data ByteString = PS {-# UNPACK #-} !(ForeignPtr Word8) -- payload
                     {-# UNPACK #-} !Int                -- offset
                     {-# UNPACK #-} !Int                -- length
Run Code Online (Sandbox Code Playgroud)

如果我有一个返回的函数ByteString,那么给定一个输入,比如一个常量Word8,该函数将返回一个具有非确定性ForeignPtr值的ByteString - 该值将由内存管理器确定.

那么,这是否意味着返回ByteString的函数不纯?如果您使用了ByteString和Vector库,那么这似乎并非如此.当然,如果是这样的话,它将被广泛讨论(并希望在谷歌搜索之上显示).这种纯度是如何实施的?

提出这个问题的原因是我很好奇从GHC编译器的角度来看,使用ByteString和Vector对象有什么微妙之处,在构造函数中给出了ForeignPtr成员.

haskell bytestring

14
推荐指数
1
解决办法
291
查看次数

GHC中的交叉模块优化

我有一个非递归函数来计算似乎表现良好的最长公共子序列(ghc 7.6.1-O2 -fllvm标志编译),如果我Criterion在同一模块中测量它.在另一方面,如果我转换功能为模块,只导出功能(如建议在这里),然后用标准重新测量,我得到〜2倍放缓(这会消失,如果我移动的标准测回模块其中定义了函数).我尝试用INLINEpragma 标记函数,这对跨模块性能测量没有任何影响.

在我看来,GHC可能正在进行严格性分析,当函数和main(函数可以从中访问)位于同一模块中时,它可以很好地工作,但是当它们被分割时则不行.我希望有关如何模块化函数的指针,以便在从其他模块调用时表现良好.有问题的代码太大了,无法在此处粘贴 - 如果您想尝试一下,可以在此处查看.我正在尝试做的一个小例子如下(使用代码片段):

-- Function to find longest common subsequence given unboxed vectors a and b
-- It returns indices of LCS in a and b
lcs :: (U.Unbox a, Eq a) => Vector a -> Vector a -> (Vector Int,Vector Int)
lcs a b | (U.length a > U.length b) = lcsh b a True
        | otherwise = lcsh a b False

-- …
Run Code Online (Sandbox Code Playgroud)

optimization performance haskell haskell-criterion

13
推荐指数
1
解决办法
533
查看次数

调试最长公共子序列算法的性能瓶颈

我正在使用向量库和状态monad在Haskell中编写一个最长的公共子序列算法(以封装Miller O(NP)算法的非常强制性和可变性).我已经用C语言编写了一些我需要它的项目,现在我正在用Haskell编写它作为一种探索如何编写具有匹配C的良好性能的命令式网格遍历算法的方法.我用unboxed向量编写的版本对于相同的输入,它比C版本慢大约4倍(并且使用正确的优化标志编译 - 我同时使用了系统时钟和Criterion验证Haskell和C版本之间相对时间测量的方法,以及相同的数据类型,包括大输入和小输入).我一直试图弄清楚性能问题可能在哪里,并会欣赏反馈 - 有可能在这里遇到一些众所周知的性能问题,特别是在我在这里大量使用的矢量库中.

在我的代码中,我有一个名为gridWalk的函数,它最常被调用,并且还完成了大部分工作.性能下降很可能会出现,但我无法弄清楚它可能是什么.完整的Haskell代码就在这里.以下代码的片段:

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 Data.STRef (newSTRef, modifySTRef, readSTRef)
import Data.Int


type MVI1 s  = MVector (PrimState (ST s)) Int

cmp :: U.Vector Int32 -> U.Vector Int32 -> Int -> Int -> Int
cmp a b i j = go 0 i j
               where
                 n = U.length a
                 m = U.length …
Run Code Online (Sandbox Code Playgroud)

performance haskell vector

12
推荐指数
1
解决办法
673
查看次数

使用ghcjs将Haskell模块编译为Javascript

是否可以使用ghcjs?将Haskell模块编译为JS ?我玩它,但它似乎需要main在生成JS之前定义函数.下面的玩具代码:

module Test where

add :: Int -> Int -> Int
add x y = x + y 
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何使用它将其编译为JS ghcjs.如果未定义main函数,它将仅编译.hi和.o文件.如果我能想出办法来把它编译成JS(在适当的Z-encoded功能名称,以及相应的JS对象,像我们在FFI为C),然后我可以使用更强大的Haskell库,例如unordered-containersvector实现一些算法,编译成JS,并Elm通过JS FFI使用.

Fay似乎有能力做到这一点.我想首先调查一下ghcjs.

haskell ghcjs

12
推荐指数
1
解决办法
683
查看次数

在C中实现MVar?

MVar在C中是否有任何已知的Haskell实现?有一个关于如何在C++中实现它的例子.但是,我想在C中实现它 - 让我们现在只说MVar CIntC中的等价物.编写同步原语可能很棘手.所以,如果有人已经做过,我希望避免重复劳动.我完全不理解上面的C++示例,可以自信地将其转换为C语言 - 它从我的C++中很好地隐藏了算法细节 - 缺乏经验的头脑:)

我想在C中编写MVar的原因是因为它使我很容易使用FFI绑定到外部C库来获取数据流,并使用Haskell线程来获取数据(来自Storable向量以避免编组数据 - MVar CInt在这里存储了多少可存储的向量.我需要确保在Haskell线程读取数据时阻塞写入Storable位置的C线程.这就是C侧的MVar同步有帮助的地方.从Haskell调用不安全甚至安全的C函数(在我的测试中安全性约为15ns,在测试中安全性约为150ns)比从C调用Haskell(~5us)要快得多.如果回调很快,我会将C函数回调到Haskell,并在Haskell MVar上阻塞.

更新:

伪代码中的算法也可以.考虑到newEmptyMVar,takeMVar和putMVar的算法,在C中实现它应该很容易.

c synchronization haskell ffi

11
推荐指数
1
解决办法
816
查看次数

尝试一些Yesod示例时编译错误

我正在尝试Yesod在Yesod网页上记录的书籍示例.其中一个示例是Wiki中嵌入的聊天应用程序.当我在ghci(加载Chat模块,Wiki.hs其中包含Wiki示例代码)中尝试它时,我得到以下关于Chat.hs的错误:

Chat.hs:122:34:
    Could not deduce (Text.Julius.ToJavascript Text)
      arising from a use of `Text.Julius.toJavascript'
    from the context (YesodChat master)
      bound by the type signature for
                 chatWidget :: YesodChat master =>
                               (Route Chat -> Route master) -> GWidget sub master ()
      at Chat.hs:(81,15)-(83,35)
    Possible fix:
      add an instance declaration for (Text.Julius.ToJavascript Text)
    In the first argument of `Text.Julius.Javascript', namely
      `Text.Julius.toJavascript output'
    In the expression:
      Text.Julius.Javascript (Text.Julius.toJavascript output)
    In the first argument of `Data.Monoid.mconcat', namely …
Run Code Online (Sandbox Code Playgroud)

haskell yesod

9
推荐指数
2
解决办法
863
查看次数

使用Iteratee库编写"wc -l" - 如何过滤换行符?

我试图使用Haskell Iteratee库提出相当于"wc -l"的东西.下面是"wc"的代码(它只计算单词 - 类似于hackage上的iteratee示例中的代码),并且运行速度非常快:


{-# LANGUAGE BangPatterns #-}
import Data.Iteratee as I
import Data.ListLike as LL
import Data.Iteratee.IO
import Data.ByteString


length1 :: (Monad m, Num a, LL.ListLike s el) => Iteratee s m a
length1 = liftI (step 0)
  where
    step !i (Chunk xs) = liftI (step $ i + fromIntegral (LL.length xs))
    step !i stream     = idone i stream
{-# INLINE length1 #-}
main = do
  i' <- enumFile 1024 "/usr/share/dict/words" (length1 :: (Monad m) => Iteratee ByteString …
Run Code Online (Sandbox Code Playgroud)

haskell filter iterate

7
推荐指数
1
解决办法
446
查看次数

维修和DPH之间的区别

最近,我读了纸张在即将到来的广义流的融合vectorDPH图书馆.这似乎是非常有趣的发展.我现在开始尝试DPH(从GHC 7.6开始,并计划在它出来时升级到7.8 SIMD版本).我还从Repa库文档中看到它可以执行并行数组工作.Repa似乎是成熟的版本,相比之下DPH,GHC 7.4没有被认为是准备好的.现在,DPH似乎是成熟的,我想知道什么是之间的主要优点和缺点RepaDPH封装,GHC 7.6.我搜索了StackOverflow和谷歌,但找不到Repa和之间的比较DPH.因此,这个问题.

haskell repa data-parallel-haskell

7
推荐指数
1
解决办法
578
查看次数