Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell:尝试并行实现“AtomicModifyOref”_Haskell_Concurrency_Ioref - Fatal编程技术网

Haskell:尝试并行实现“AtomicModifyOref”

Haskell:尝试并行实现“AtomicModifyOref”,haskell,concurrency,ioref,Haskell,Concurrency,Ioref,据我所知,对IORefs的修改非常快,所涉及的只是更新thunk指针。当然,读者(即希望在其网页上看到价值的人)需要花时间来评估这些恶作剧(如果作者没有阅读结果,这些恶作剧可能会增加) 我认为最好开始并行地评估IORef上的修改thunk,因为在许多情况下,它们可能无论如何都必须在某个点上进行评估(显然,这将破坏无限的数据结构) 因此,我编写了以下函数,其签名与atomicModifyIORef类似: atomicModifyIORefPar :: (NFData a) => IORef

据我所知,对
IORef
s的修改非常快,所涉及的只是更新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

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

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


编辑-第二次尝试回答


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

对我来说很好,但不知何故,当原子性很重要时,我希望使用
MVar
而不是
IORef
。您不能定义IORef strict吗?像IORef!Bla@VagifVerdi:在计算修改函数之前,还会锁定
IORef
,这难道不会减慢编写程序的速度吗?@vagiverdi否,您只能将严格性注释添加到值构造函数,而不能添加到类型构造函数。并且IORef的值构造函数是隐藏的。(更不用说克林顿的反对了,即使有可能也是有效的。)@VagifVerdi没有。Bla的内容会很严格,但IORef的内容不会很严格。因此,当你在IORef上操作时,你会得到未经评估的指向Bla的Thunk。评估其中一个也会导致同时评估其所有严格的参数,但不是在评估之前。您能对我在上面编辑的问题中提出的解决方案发表意见吗?
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