【发布时间】:2013-06-08 15:25:24
【问题描述】:
这是question 的延续。由于向量库似乎没有可融合的 O(1) 更新函数,我想知道是否可以编写不涉及 unsafeFreeze 和 unsafeThaw 的可融合 O(1) 更新函数。我猜它会使用vector stream 表示-我不熟悉如何使用stream 和unstream 编写一个-因此,这个问题。原因是这将使我们能够在向量上编写一个缓存友好的更新函数,其中只有一个狭窄的向量区域被修改,因此,我们不想遍历整个向量来处理那个狭窄的区域(并且此操作在每个函数调用中可能发生数十亿次 - 因此,保持开销非常低的动机)。像map 这样的转换函数会处理整个向量 - 所以它们会太慢。
我有一个我想做的玩具示例,但是下面的 upd 函数使用了 unsafeThaw 和 unsafeFreeze - 它似乎没有在核心中进行优化,并且也违反了不再使用缓冲区:
module Main where
import Data.Vector.Unboxed as U
import Data.Vector.Unboxed.Mutable as MU
import Control.Monad.ST
upd :: Vector Int -> Int -> Int -> Vector Int
upd v i x = runST $ do
v' <- U.unsafeThaw v
MU.write v' i x
U.unsafeFreeze v'
sum :: Vector Int -> Int
sum = U.sum . (\x -> upd x 0 73) . (\x -> upd x 1 61)
main = print $ Main.sum $ U.fromList [1..3]
我知道如何使用STVector 实现命令式算法。如果您想知道为什么使用这种替代方法,我想尝试这种使用纯向量的方法来检查特定算法的GHC 转换在使用可熔纯向量流编写时有何不同(当然还有单子操作) .
当使用STVector 编写算法时,它似乎不像我希望的那样迭代(我猜当存在大量可变性时,GHC 优化器更难发现循环)。所以,我正在研究这种替代方法,看看我可以在那里获得更好的循环。
【问题讨论】:
-
unsafeFreeze/Thaw 显然是为了更新向量,否则向量的纯度会被破坏。
标签: haskell vector stream fusion