1
整数の行列をArrayArray#
として実装しようとしています。それは私に速いswapLines
オペレーションを与えるはずです。それはいくつかの整数をコピーするのではなく、メモリ内にネイティブポインタを書き込むだけです。すべてのタイプが解除されているため、メモリの方向はVector (Unboxed.Vector Int)
より少なくする必要があります。Segfault in ArrayArray#
小さな行列の場合はうまく動作しますが、サイズを大きくするとセグメンテーションが失敗します。
{-# language CPP #-}
-- imports
#include "MachDeps.h"
そしてコードで:
case newByteArray# (SIZEOF_HSINT# *# colCount) s of
あなたはMachDeps.h
hereの内容を見つけることができますあなたがTODO sizeof Int
を行う場合、それは大丈夫と思われる、crashBigMatrix
を実行している
{-# LANGUAGE MagicHash, UnboxedTuples #-}
module Matrix where
import Control.Monad.ST
import GHC.ST
import GHC.Exts
import GHC.Prim
import GHC.Magic(runRW#)
data Matrix = Matrix ArrayArray# -- lifts the array from # to *
data MutableMatrix s = MutableMatrix (MutableArrayArray# s)
generateLine :: MutableByteArray# s -> Int# -> Int# -> Int# -> (Int -> Int -> Int) -> State# s -> State# s
generateLine mbar curLine curCol colCount genFunc s =
case curCol ==# colCount of
0# -> case genFunc (I# curLine) (I# curCol) of
(I# x) -> generateLine mbar curLine (curCol +# 1#) colCount genFunc (writeIntArray# mbar curCol x s) -- if curCol is replaced by 0#, doesn't crash
_ -> s
initLines :: MutableArrayArray# s -> Int# -> Int# -> Int# -> (Int -> Int -> Int) -> State# s -> State# s
initLines mat curLine lineCount colCount genFunc s =
case curLine ==# lineCount of
1# -> s
0# -> case newByteArray# (4# *# colCount) s of -- TODO sizeof Int ?
(# s1, mbar #) -> case unsafeFreezeByteArray# mbar (generateLine mbar curLine 0# colCount genFunc s1) of
(# s2, bar #) -> initLines mat (curLine +# 1#) lineCount colCount genFunc
(writeByteArrayArray# mat curLine bar s2) -- only writes a pointer to the ByteArray
generateMutable# :: Int# -> Int# -> (Int -> Int -> Int) -> State# s -> (# State# s, MutableArrayArray# s #)
generateMutable# lineCount colCount genFunc s =
case newArrayArray# lineCount s of
(# s1, marrarr #) -> (# initLines marrarr 0# lineCount colCount genFunc s1 , marrarr #)
crashBigMatrix :: Int
crashBigMatrix =
case (runRW# $ \s -> case generateMutable# 150000# 4# (\x y -> x) s of
(# s1, marrarr #) -> (# s1, marrarr #)) of
(# _, m #) -> (MutableMatrix m) `seq` 2
実際。私は 'Int#'がハスケルで64ビットだったのを知らなかった、ありがとう! –
これは使用しているGHCのビルドによって異なります。 – MathematicalOrchid
もう少し拡張する:Haskellレポートは、 'Int'が少なくとも29ビットの精度を持つことを保証します。 GHCの32ビットビルドは 'Int#'を32ビットとして実装し、GHCの64ビットビルドはそれを64ビットとして実装します。 'GHC.Prim'のコメントを見てください。 – MathematicalOrchid