gpt4 book ai didi

haskell - 如何将 Haskell 数据类型存储在连续内存中的未装箱向量中

转载 作者:行者123 更新时间:2023-12-02 16:04:14 26 4
gpt4 key购买 nike

我想存储非参数、未打包的数据类型,例如

data Point3D = Point3D {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int

在未装箱的向量中。 Data.Vector.Unboxed说:

In particular, unboxed vectors of pairs are represented as pairs of unboxed vectors.

这是为什么呢?我更愿意将我的 Point3D 放置在内存中一个接一个,以便在顺序迭代它们时获得快速的缓存本地访问 - 相当于 mystruct[1000 ] 在 C 语言中。

使用Vector.Unboxed或其他方式,我怎样才能实现这一点?

<小时/>

顺便说一句:与 vector-th-unbox同样的情况也会发生,因为您只需将数据类型转换为 (Unbox a, Unbox b) => Unbox (a, b) instance .

最佳答案

我不知道为什么向量对存储为向量对,但您可以轻松地为数据类型编写实例来按顺序存储元素。

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses #-}

import qualified Data.Vector.Generic as G
import qualified Data.Vector.Generic.Mutable as M
import Control.Monad (liftM, zipWithM_)
import Data.Vector.Unboxed.Base

data Point3D = Point3D {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int

newtype instance MVector s Point3D = MV_Point3D (MVector s Int)
newtype instance Vector Point3D = V_Point3D (Vector Int)
instance Unbox Point3D

此时,最后一行将导致错误,因为没有 Point3D 的矢量类型实例。它们可以写成如下:

instance M.MVector MVector Point3D where 
basicLength (MV_Point3D v) = M.basicLength v `div` 3
basicUnsafeSlice a b (MV_Point3D v) = MV_Point3D $ M.basicUnsafeSlice (a*3) (b*3) v
basicOverlaps (MV_Point3D v0) (MV_Point3D v1) = M.basicOverlaps v0 v1
basicUnsafeNew n = liftM MV_Point3D (M.basicUnsafeNew (3*n))
basicUnsafeRead (MV_Point3D v) n = do
[a,b,c] <- mapM (M.basicUnsafeRead v) [3*n,3*n+1,3*n+2]
return $ Point3D a b c
basicUnsafeWrite (MV_Point3D v) n (Point3D a b c) = zipWithM_ (M.basicUnsafeWrite v) [3*n,3*n+1,3*n+2] [a,b,c]

instance G.Vector Vector Point3D where
basicUnsafeFreeze (MV_Point3D v) = liftM V_Point3D (G.basicUnsafeFreeze v)
basicUnsafeThaw (V_Point3D v) = liftM MV_Point3D (G.basicUnsafeThaw v)
basicLength (V_Point3D v) = G.basicLength v `div` 3
basicUnsafeSlice a b (V_Point3D v) = V_Point3D $ G.basicUnsafeSlice (a*3) (b*3) v
basicUnsafeIndexM (V_Point3D v) n = do
[a,b,c] <- mapM (G.basicUnsafeIndexM v) [3*n,3*n+1,3*n+2]
return $ Point3D a b c

我认为大多数函数定义都是不言自明的。点向量存储为 Int 向量,第 n 个点是 3n,3n+1 code>,3n+2 Int

关于haskell - 如何将 Haskell 数据类型存储在连续内存中的未装箱向量中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22882228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com