Should 'ref' implementation be changed to 'Atomic' now?

Now that we are entering the world of multicore, I assume we will want to use Atomic in preference to refs? In fact, is there anything stopping us from changing the internal implementation of ref to:

type 'a ref = 'a Atomic.t

let ( := ) = Atomic.set
let ( ! ) = Atomic.get
let incr = Atomic.incr
let decr = Atomic.decr

The obvious answer is performance. Currently the Atomic module goes through C code for its operations. This will likely be switched to compiler primitives at some point, but it’s unlikely to be as performant as regular references. And you can’t perform the same optimisations either.

However it could make sense to develop a ppx that replaces references and other mutable records by atomic operations as a way to quickly port existing libraries to multicore. That should not become a long-term solution though.

1 Like

That would hurt performance a lot. Some references are short lived, local loop counter or loop accumulators. In the best case, OCaml can eliminate them entirely and use registers. Using atomics there (even if they were compiled to assembly instructions directly) would be a noticeable slowdown.

5 Likes

Yes, IIRC, atomic operations need to be implemented with cache barriers and flushes and such in order to ensure an intelligible memory-model in the face of SMP. I don’t recall the details, but this was something that had to be carefully-worked-out for Java, and I’m sure the same is true for Multicore OCaml. Switching all refs over to Atomics would incur this hardware concurrency overhead for them, when one would presume that in fact most refs (and most mutables) aren’t visible from multiple threads.

3 Likes

All great answers. Thanks all. I hadn’t been thinking about local mutation, but of course, it’s super common.