3 ms·
Oh, you suppose the authors spent their time writing that for no reason? You know better than them? Your explanation is so incomplete I hardly know where to beg
by notacoward 3y ago
Oh, you suppose the authors spent their time writing that for no reason? You know better than them? Your explanation is so incomplete I hardly know where to begin. Maybe with the fact that you're talking about local ordering as it may or may not be perturbed by a compiler, while the document is talking about the observed order elsewhere (other processors or main memory). That observed order can vary depending on the processor's ordering model, and to ensure it (e.g. across all modifications to a complex shared data structure) without doing the memory equivalent of an fsync() on every file write (disastrous!) you need memory barriers. All of the bugs I mentioned, all of which were crashes, were related to exactly the distinction you're missing. Yours is the kind of mythology that OP sought to address. Please read the document - particularly the section on CPU memory barriers and anywhere that mentions Alpha - before spreading more misinformation.
- jcranmer 3y ago> Oh, you suppose the authors spent their time writing that for no reason? Your explanation is so incomplete I hardly know where to begin. No. I am suggesting that you don't need the full rigor of understanding the memory barrier semantics to be able to effectively write multithreaded code correctly. Completeness was never a goal of my explanation; sufficiency was. Furthermore, my focus is on a software memory model, not the hardware memory model. > Maybe with the fact that doing acquire/release for one value has varying effect (sometimes none) on others, so you'd have to do it separately for all of the many values that might have changed. You have misinterpreted my words, I think. At no point do I suggest that you should insert an acquire/release for each, individual value. Rather, you need to do an acquire at the beginning of a block of code (wherein you can read and write multiple values) and a release at the end of a block of code, much as you would with a mutex (except it's not necessary that the regions of code actually be mutually excluded from executing on multiple threads). The only requirement is that the store be followed by a release operation that crosses threads to an acquire operation that is followed by a load. > Then we can move on to the concept of dependent reads, and so on. I allude to those under the part where I mention "There is a theoretical slight relaxation of the above model that works on most hardware called release-consume in the C/C++ memory model." That you did not pick up on that is perhaps because you yourself are unfamiliar with the release-consume portion of the C/C++ memory model. If you need a refresher, I might point you to the thread where I actually go into why it exists, and why it's not implemented by compilers, here: https://news.ycombinator.com/item?id=36059369 https://news.ycombinator.com/item?id=36059369. (There's a reason I'm not going into it in a facile explanation!) > Please read the document before you spread more misinformation. Oh, do trust me, I have read that document, and far more, on memory models. I am not spreading misinformation. Perhaps my word choice and my writing is inartful or oversimplified in the goal of making the topic more accessible rather than seeking to enshrine comprehensive knowledge in thick tomes that many will give up reading. Perhaps you yourself may not be sufficiently informed as to pick up on the specific terminology that I use, which derives from the dominant memory model in use by, well, everybody.
- notacoward 3y ago> dominant memory model in use by, well, everybody. "...by, well, x86" Fixed that for you.
- jcranmer 3y agoNo, you didn't. It's the C++ memory model, which is borrowed by C, then every compiler IR targeting something in the C/C++ space, and then every other language that decided to support language-level atomics. Your mistake is thinking solely in terms of the hardware memory model. Indeed, if you care only about x86 (and ignore the potential for compiler optimizations), most of the variety provided by the C/C++ memory model is unnecessary, as every operation on the x86 (well, except for the exceptions) are inherently release/acquire operations. Please do read up on the C/C++ memory model added in C11 and C++11. It may serve you to understand this space better.
- notacoward 3y agoSo your incomplete explanations are based on a single language model instead of a single processor model? Sorry, that's a distinction without a difference. It's no excuse for misleading people who might use other languages or processors. And stop with the implied insults about my level of knowledge, when you're the one clearly fixated on only one environment. That's both rude and stupid. I've worked on many CPU architectures, on NUMA and COMA systems long before most people even knew such things existed, at many different levels from the first instruction after an exception (or restart) on up. I say that not to make my own appeal to authority, but to refute yours and to underscore that these "irrelevant" details are in fact highly relevant and important to some of us out here in the wider world. I haven't been alone in any of those things. There are still many programmers working in "exotic" environments where these things matter, and we both rely on their work every day. You should at the very least qualify your statements to say that they're only true for application level programmers like yourself.
- jcranmer 3y ago> So your incomplete explanations are based on a single language model instead of a single processor model? It's the language memory model incorporated by all major programming languages. That you are unaware of this tells me that you are a hardware engineer, not a software engineer. > I've worked on many CPU architectures And I've worked on computer architectures where it's not clear how to even translate "volatile" correctly because the memory system is that weird. I didn't bring that up before because I'm not interested in appeal-to-authority until people start accusing me of being an idiot who doesn't know what they talk about. I could bring up more bona fide credentials, but what's the point? You've already dismissed my expertise. > You should at the very least qualify your statements to say that they're only true for application level programmers like yourself. I did. Every single message, in fact: > what most programmers would need to understand about memory ordering > Furthermore, my focus is on a software memory model, not the hardware memory model. > It's the C++ memory model And actually, I would go further and suggest that kernel programmers might be better served by adopting the language memory model offered by their compiler rather than insisting on rolling their own and yelling at the compiler when they mess it up.