Haskell: attempting parallel implementation of `atomicModifyIORef`

From what I understand, changes are IORefvery quick, all they are related to is updating the thunk pointer. Of course, it will take a reader (i.e., someone who wants to see value on their web page) to appreciate these tricks (which can occur if authors do not read the results).

I thought it would be nice to actually start evaluating thunks modifications in IORefparallel, as in many cases they will probably have to be evaluated at some point (obviously, this will break with endless structure data).

So, I wrote the following function with a similar signature to 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

Seems to work ( test code here ). Am I doing something wrong? Or is there a better way to do this?


Edit: second attempt

Carl's Inspired Answer below . In fact, we store force newdatain IORef. This is the same as newdatain any case, but it shows the runtime that we want to save force newdatafor later, so this is not garbage collecting a spark.

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
+3
source share
1 answer

, GHC. GC . , force newdata atomicModifyIORefPar, , , , , par -, , , .

GHC GC, . , , , GC. , ( parallelism, ) , , GC ( , ).


-

, , . , , GC.

+4

All Articles