To clarify, my op was to understand if this could be done in Go, which Bruno showed it can, and know I’d like to know why the race detector is not complaining…
I wasn’t making any attempt at creating a more specified Go memory model. It is what it is. > On Jan 31, 2025, at 12:09 PM, robert engels <reng...@ix.netcom.com> wrote: > > Yes, Java has a very detailed and explicit memory model which makes things > like this doable. > > Although the ideas you propose are workable, the primary purpose of this is > performance based - otherwise you would simply use a mutex. The problem with > making every shared variable an atomic is that you pay the atomic/fence cost > on every access - read and write. Whereas in the Java case, there is no > flushing of the cache at all if there has been no writer activity, and even > if there is, it is a single cache flush per “bulk update”. > > There reason StampedLock is provided rather than modifying Point is DRY. If > you need a highly concurrent shared data system (i know, don’t share data in > Go…) which is often the case for HPC/HFT systems, StampedLock can be useful. > > Using channels and locks is simply too slow - see > github.com/robaho/go-concurrency-test > <http://github.com/robaho/go-concurrency-test> (old, but I think still > applicable). > > I think a more viable performant replacement in Go is to use copy on write > with an atomic object reference - which in most cases is going to be more > performant than using a StampedLock. > >> On Jan 31, 2025, at 11:55 AM, 'Michael Knyszek' via golang-nuts >> <golang-nuts@googlegroups.com> wrote: >> >> This is a well-known pattern (use an atomic counter to check if anyone else >> modified some data in a critical section and retry or fall back if it >> happened), but as the extensive Java docs imply, any such abstraction is >> going be fairly leaky. Java has a very thoroughly defined memory model that >> I suspect comes into play here to make the abstraction more usable (but >> don't quote me on that). >> >> You *could* do a very close read of the Go memory model and try to do >> something similar but you end up pushing a lot of these subtleties onto the >> caller. This would also require //go:norace annotations on the caller to not >> fail in the race detector. Neither I nor the memory model docs recommend >> this. >> >> The pattern is still useful and possible to apply in Go, however I have two >> suggestions: >> 1. Take the abstraction one level higher. Using the Java doc's Point >> example, what I mean is to only provide Point, not StampedLock. It's not too >> hard to implement a bespoke version of this sort of thing when you need it, >> and I find that doing these sorts of tricks benefits from breaking down the >> abstraction internally anyway, since it gives you more flexibility when >> adding new features. >> 2. Read and write the optimistically-read variables using the sync/atomic >> package. In the Point example from the Java docs, the optimistic read path >> would load x and y atomically (i.e. two separate Loads) and any write paths >> would store x and y atomically (i.e. two separate Stores). That's going to >> be far easier to reason about and more portable, though it might not achieve >> maximum performance on your hardware. If you're doing mostly optimistic >> reads (which I suspect is really when you'd want to consider this anyway), >> the optimistic reads themselves should scale just as well and you won't need >> to apply any //go:norace annotations. This suggestion is in the same vein as >> the "don't be clever" part of the memory model documentation. >> >> On Friday, January 31, 2025 at 6:14:24 AM UTC-5 Robert Engels wrote: >>> Hi, >>> >>> Do you think it is possible to implement a stamped lock in Go >>> https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/StampedLock.html >>> ? >>> >>> It would seem that the Go race detector would always report the “optimistic >>> read” mode as a data race? >>> >>> (The docs state for Java that the values can be wildly inconsistent when >>> the optimistic read fails). >>> >>> Ideas on how to implement in Go? >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com >> <mailto:golang-nuts+unsubscr...@googlegroups.com>. >> To view this discussion visit >> https://groups.google.com/d/msgid/golang-nuts/10e6c142-fbdb-4c8d-8270-a836ab4cecf8n%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/10e6c142-fbdb-4c8d-8270-a836ab4cecf8n%40googlegroups.com?utm_medium=email&utm_source=footer>. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/7076427B-A95E-44E2-B3DE-165F960E52F1%40ix.netcom.com.