【问题标题】:Haskell: Attempt at parallel `atomicModifyIORef` implementationHaskell:尝试并行`atomicModifyIORef`实现
【发布时间】:2012-04-18 05:40:42
【问题描述】:

据我了解,对IORefs 的修改非常快,所涉及的只是更新一个thunk 指针。当然,读者(即想要在其网页上查看价值的人)将需要花时间评估这些 thunk(如果作者没有回读结果,这可能会增加)。

我认为最好开始并行评估 IORef 上的修改 thunk,因为在许多情况下,它们可能无论如何都必须在某个时候进行评估(显然,这会因无限数据而中断结构)。

所以我写了以下函数,签名与atomicModifyIORef类似:

atomicModifyIORefPar :: (NFData a) => IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORefPar ioref f =
  let 
    g olddata = 
      let (newdata, result) = f olddata in (newdata, (result, newdata))
  in do
    (result, newdata) <- atomicModifyIORef ioref g
    force newdata `par` return result

这似乎有效 (test code here)。我在这里做错了什么吗?或者有更好的方法吗?


编辑:第二次尝试

灵感来自Carl's answer below。我们实际上将force newdata 存储到IORef 中。无论如何,这与newdata 相同,但它显示了我们想要保留force newdata 以供以后使用的运行时,因此它不会垃圾收集火花。

atomicModifyIORefPar :: (NFData a) => IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORefPar ioref f =
  let 
    g olddata = 
      let 
        (newdata, result) = f olddata
        newdata_forced = force newdata
      in 
        (newdata_forced, (result, newdata_forced))
  in do
    (result, newdata_forced) <- atomicModifyIORef ioref g
    newdata_forced `par` return result

【问题讨论】:

  • 对我来说看起来不错,但不知何故,当原子性很重要时,我会期望 MVar 而不是 IORef
  • 你不能定义 IORef strict 吗?像 IORef !Bla
  • @VagifVerdi:这不会减慢编写者的速度,还会锁定IORef,直到计算出修改函数?
  • @VagifVerdi 不行,你只能给值构造函数添加严格注解,不能给类型构造函数。 IORef 的值构造函数是隐藏的。 (更不用说克林顿的反对了,即使这可能是有效的。)
  • @VagifVerdi 不。Bla 的内容会很严格,但 IORef 的内容不会很严格。因此,当您对 IORef 进行操作时,您会得到指向 Bla 的未经评估的 thunk。评估其中之一也会导致同时评估其所有严格参数 - 但不是之前。

标签: haskell concurrency ioref


【解决方案1】:

这可能有效也可能无效,具体取决于 GHC 的版本。火花池与 GC 的交互在历史上一直是可变的。在某些版本中,表达式force newdataatomicModifyIORefPar 返回后没有被范围内的任何东西引用,这意味着它很可能在par 创建的火花被转换之前被垃圾收集,这意味着火花也会被收集。

其他版本的 GHC 已将火花池视为 GC 分析的根源,但这也存在问题。我不记得当前状态是什么,但我怀疑火花池不算作 GC 根。它引发的问题(当返回的表达式不引用被并行评估的表达式时,并行性丢失)比将火花池视为 GC 根(保留不需要的内存)所产生的问题要好。


编辑 - 第二次尝试回答

由于您给出的原因,这个新实现看起来不错。并行计算的表达式也可以从 GC 根中访问。

【讨论】:

  • 您能评论一下我在上面编辑过的问题中提出的解决方案吗?
猜你喜欢
  • 2012-04-23
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多