小编NBF*_*RTW的帖子

Haskell/GHC:{ - #SPECIALIZE# - }导致'RULE左手边太复杂到desugar'警告

我有一个代码体,使用monad来抽象实际实现是在ST还是IO内运行.由于内联和缺少类型类函数调用开销,删除额外的抽象层并且只是替换具体类型会产生巨大的加速(~4.5x).我想通过使用specialize pragma来获得一些性能,但是我从编译器得到了一个相当无意义的警告.我不能做一个简单的复制案例,因为这个简单的例子似乎有用,而且我不知道是什么导致我的实际程序有所不同.

基本上,我的程序执行此操作:

{-# LANGUAGE FlexibleInstances, RankNTypes #-}

module STImpl (runAbstractST, MonadAbstractIOST(..), ReaderST) where

import Control.Monad.Reader
import Control.Monad.ST

class Monad m => MonadAbstractIOST m where
    addstuff :: Int -> m Int

type ReaderST s = ReaderT (Int) (ST s)

instance MonadAbstractIOST (ReaderST s) where
    addstuff a = return . (a +) =<< ask

runAbstractST :: (forall s. ReaderST s a) -> a
runAbstractST f = runST $ runReaderT f 99
Run Code Online (Sandbox Code Playgroud)

module Main (main) where

import STImpl

import Control.Monad

{-# …
Run Code Online (Sandbox Code Playgroud)

haskell pragma ghc

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

在Haskell的ST Monad中有效记录字符串数据

我有一个Haskell程序,它在ST monad中运行期间生成~280M的日志文本数据.这几乎是所有内存消耗的地方(禁用日志记录,程序分配总计3MB的实内存).

问题是,我的内存不足.虽然程序运行内存消耗超过1.5GB,但它最终在尝试将日志字符串写入文件时耗尽.

log函数接受String并将日志数据累积到存储在环境中的STRef中的字符串构建器中:

import qualified Data.ByteString.Lazy.Builder as BB
...
myLogFunction s = do
    ...
    lift $ modifySTRef myStringBuilderRef (<> BB.stringUtf8 s)
Run Code Online (Sandbox Code Playgroud)

我尝试使用bang模式和modifySTRef'来引入严格性,但这使得内存消耗更加糟糕.

我按照hPutBuilder文档的建议编写日志字符串,如下所示:

    hSetBinaryMode h True
    hSetBuffering  h $ BlockBuffering Nothing
    BB.hPutBuilder h trace
Run Code Online (Sandbox Code Playgroud)

这会消耗几个额外的GB内存.我尝试了不同的缓冲设置并首先转换为懒惰的ByteString(略胜一筹).

QS:

  • 如何在程序运行时最小化内存消耗?我希望给出一个严格的ByteString表示和适当的严格程度,我需要的内存比我存储的~280M的实际日志数据要多得多.

  • 如何在不分配内存的情况下将结果写入文件?我不明白为什么Haskell需要GB的内存来将一些驻留数据流式传输到文件中.

编辑:

这是小运行的内存配置文件(大约42MB的日志数据).禁用日志记录时总内存使用量为3MB.

    15,632,058,700 bytes allocated in the heap
     4,168,127,708 bytes copied during GC
       343,530,916 bytes maximum residency (42 sample(s))
         7,149,352 bytes maximum slop
               931 MB total memory in use (0 MB lost due to fragmentation)

                                      Tot time (elapsed)  Avg pause  Max …
Run Code Online (Sandbox Code Playgroud)

logging haskell out-of-memory lazy-evaluation bytestring

6
推荐指数
1
解决办法
361
查看次数

Haskell:ST/GC泄漏的内存没有收集?

我在ST内部有一个计算,它通过Data.Vector.Unboxed.Mutable分配内存.永远不会读取或写入向量,也不会在runST之外保留任何引用(据我所知).我遇到的问题是,当我多次运行ST计算时,我有时似乎会保留向量的内存.

分配统计:

5,435,386,768 bytes allocated in the heap
    5,313,968 bytes copied during GC
  134,364,780 bytes maximum residency (14 sample(s))
    3,160,340 bytes maximum slop
          518 MB total memory in use (0 MB lost due to fragmentation)
Run Code Online (Sandbox Code Playgroud)

在这里,我将runST 20x调用为计算的不同值和128MB向量(再次 - 未使用,未返回或在ST之外引用).最大居住率看起来不错,基本上只是我的矢量加上几MB的其他东西.但总内存使用量表明我有四个同时激活的向量副本.这与矢量的大小完美匹配,对于256MB,我们按预期获得1030MB.

使用1GB向量耗尽内存(4x1GB +开销> 32位).我不明白为什么RTS保持看似未使用的,未引用的内存而不仅仅是GC,至少在分配会失败的时候.

使用+ RTS -S运行会显示以下内容:

    Alloc    Copied     Live    GC    GC     TOT     TOT  Page Flts
    bytes     bytes     bytes  user  elap    user    elap
134940616     13056 134353540  0.00  0.00    0.09    0.19    0    0  (Gen:  1)
   583416      6756 134347504  0.00  0.00    0.09    0.19    0 …
Run Code Online (Sandbox Code Playgroud)

garbage-collection haskell out-of-memory ghc

6
推荐指数
1
解决办法
424
查看次数

OS X“堆”命令行实用程序如何收集其信息?

OS X“堆”命令行实用程序显然可以枚举不同的 malloc 区域以及任何正在运行的进程的各个 malloc 块。它不需要与任何特殊的调试库链接,也不需要为目标进程设置任何调试堆环境变量。

它使用哪种底层机制来做到这一点?我发现的所有 malloc 调试 API 都需要在进程内部设置挂钩、链接特殊调试库或在启动进程之前设置调试环境变量。据我所知,该实用程序的源代码不可用,并且在 Google 和 Apple.com 上进行的大量搜索没有显示任何有用的信息。

我最感兴趣的是获取实际分配的内存总和,因为进程的驻留大小通常会比应用程序代码实际请求的大小显着增加。

谢谢!

c++ memory malloc macos heap-memory

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