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.

Reply via email to