Live data from Hacker News

Programming Language Memory Models

research.swtch.com

81–90 of 101 posts

Re: Programming Language Memory Models

#81

These "memory models" are too complex for languages intended for dilettante developers. It was a disaster in Java/C#. Not even more than a handful of programmers in existence know in depth how it works, as in, can they understand any given trivial program in their language. At best they only know some vague stuff like that locking prevents any non visibility issues. It goes far deeper than that though (which is also…

> Go has lots of weird edge cases, like sharing a slice across threads can lead to memory corruption (in the C / assembly sense, not merely within that array) Source?

https://research.swtch.com/gorace

Re: Programming Language Memory Models

#82

These "memory models" are too complex for languages intended for dilettante developers. It was a disaster in Java/C#. Not even more than a handful of programmers in existence know in depth how it works, as in, can they understand any given trivial program in their language. At best they only know some vague stuff like that locking prevents any non visibility issues. It goes far deeper than that though (which is also…

If "not even more than a handful of programmers" understand something, then it's objectively wrong to refer to all programmers - approximately all programmers - as "dilletantes".

Also, maybe you are different, but I can only keep so much in my head at a time. If I can keep something simple or abstract it away so I can focus on other details, that doesn't make me a dilletante. It makes me more effective at what I'm actually trying to do.

Re: Programming Language Memory Models

#83
post #49

Earlier quoted context omitted.

In a lot of code I've seen, there are threads polling some variable without using any sort of special guard. The assumption (based, I assume, on how you really could get away with this back in the days of single-core, single-CPU computers) is that you only need to worry about race conditions when writing to primitive variables, and that simply reading them is always safe.

Okay but the poster mentioned a mutex, which would not be a good way to go about polling a variable in Java. All you need to guarantee synchronization of primitive values in Java is the use of volatile [1]. If you need to compose atomic operations together, then you can use an atomic or a mutex, but it would not occur to me to use a mutex to perform a single atomic read or write on a variable in Java. [1] https://doc…

> All you need to guarantee synchronization of primitive values in Java is the use of volatile

I think I know what you mean, but that's a very dangerous way to word it when speaking in public. It would be more correct to say that "all you need to guarantee reads are protected by memory barriers is volatile."

The distinction matters because, to someone who doesn't already know all about volatile, the way you worded it might lead them to believe that `x++;` is an atomic statement if x is volatile, which is not true. That's a specific example of where things like atomic types are necessary.

(For the curious: https://www.baeldung.com/java-atomic-variables)

I think maybe what you're missing about what I'm saying is that I'm trying to mainly talk for the benefit of people who don't have a solid understanding of how to do safe and performant multithreading. Which is the vast majority of programmers. For that sort of audience, I tend to agree with dragontamer that "just use a mutex" is probably the safest advice to start out. Producing results faster doesn't count for much if you're producing wrong results faster.

Re: Programming Language Memory Models

#84

These "memory models" are too complex for languages intended for dilettante developers. It was a disaster in Java/C#. Not even more than a handful of programmers in existence know in depth how it works, as in, can they understand any given trivial program in their language. At best they only know some vague stuff like that locking prevents any non visibility issues. It goes far deeper than that though (which is also…

> Go has lots of weird edge cases, like sharing a slice across threads can lead to memory corruption (in the C / assembly sense, not merely within that array) Source?

https://blog.stalkr.net/2015/04/golang-data-races-to-break-m...

The "Exploiting the slice type" section.

Re: Programming Language Memory Models

#85
post #82

These "memory models" are too complex for languages intended for dilettante developers. It was a disaster in Java/C#. Not even more than a handful of programmers in existence know in depth how it works, as in, can they understand any given trivial program in their language. At best they only know some vague stuff like that locking prevents any non visibility issues. It goes far deeper than that though (which is also…

If "not even more than a handful of programmers" understand something, then it's objectively wrong to refer to all programmers - approximately all programmers - as "dilletantes". Also, maybe you are different, but I can only keep so much in my head at a time. If I can keep something simple or abstract it away so I can focus on other details, that doesn't make me a dilletante. It makes me more effective at what I'm ac…

Not sure why people keep deducing this point I have not made. I said Go markets to dilletante programmers, which is a reason to make it simpler, not more complex. Any language with "the memory model" is complex. I do not fully grasp the memory model, either, as it requires full time investment.

Re: Programming Language Memory Models

#86

Earlier quoted context omitted.

Its not true in general. x86 CANNOT have weak acquire/release semantics. x86 is "too strong", you get total-store ordering by default. If you want to test out weaker acquire/release semantics, you need to buy an ARM or POWER9 processor.

I would say that acquire/release map very well to x86 (were they are free). Technically x86 is slightly stronger as it doesn't allow IRIW, but seq cst is too expensive to implement by default. Conversely acq/rel are from somewhat to very expensive to implement on ARM/POWER.

Acq/rel are nonsense on x86, worse than a NOP. It compiles down into nothing.

x86 cannot specify a load/store any more relaxed than total-store ordering (which is even "stronger" than acquire/release)

ARM / POWER9 were originally "consume/release". But upon C++11, the agreement was that consume/release was too complicated, and acquire/release model was created instead.

Java was the granddaddy of modern memory models but focused on Seq-Cst (the strongest model: the one that makes "sense" to most programmers). C++ inherited Java's seq-cst, but recognized that low-level programmers wanted something faster: both "fully relaxed" and acq/rel as the two faster ways to load/store.

Re: Programming Language Memory Models

#87
Fascinating article. I've been doing research in this area and I wonder if there was exploration for JinjaThreads - which operate on Jinja (a Java-like language) that does a formal DRF proof guarantee (coincidentally using Isabelle/HOL).

You can read more about this here if you're interested: https://www.isa-afp.org/entries/JinjaThreads.html

Re: Programming Language Memory Models

#88

Earlier quoted context omitted.

https://doc.rust-lang.org/std/sync/atomic/struct.AtomicU32.h... It's accepted by the compiler, but if provided, it compiles to a panic.

On the page you linked panics are only mentioned for load and store and the code below seems to work just fine? let x = atomic::AtomicU32::new(0); x.compare_exchange_weak( 0, 1, atomic::Ordering::AcqRel, atomic::Ordering::Relaxed).unwrap(); println!("{}", x.load(atomic::Ordering::Relaxed));

Ah, you're right. I was using the same ordering for success and failure. It is possible to use AcqRel in the success case.

Re: Programming Language Memory Models

#89

Earlier quoted context omitted.

> Go has lots of weird edge cases, like sharing a slice across threads can lead to memory corruption (in the C / assembly sense, not merely within that array) Source?

https://blog.stalkr.net/2015/04/golang-data-races-to-break-m... The "Exploiting the slice type" section.

Er, your summary does not at all describe what is going on there. Like, all of that code violates the memory model, so whatever it accomplishes is irrelevant.

Re: Programming Language Memory Models

#90
post #76

A GPU followup to this article. While on CPU sequentially consistent semantics are efficient to implement, that seems to be much less true on GPU. Thus, Vulkan completely eliminates sequential consistency and provides only acquire/release semantics[1]. It is extremely difficult to reason about programs using these advanced memory semantics. For example, there is a discussion about whether a spinlock implemented in te…

Thanks for the GPU insights and links (and the paper link below)! I based my claim about Rust from https://doc.rust-lang.org/nomicon/atomics.html . ("Rust pretty blatantly just inherits the memory model for atomics from C++20.") Perhaps that is out of date?

I believe your claim is correct: https://news.ycombinator.com/item?id=27758461.
Post reply on HN