> The reason why Cosmopolitan Mutexes are so good is because I used a library called nsync. It only has 371 stars on GitHub, but it was written by a distinguished engineer at Google called Mike Burrows. Indeed this is the first time I've heard of nsync, but Mike Burrows also wrote Google's production mutex implementation at https://github.com/abseil/abseil-cpp/blob/master/absl/synchr... I'm curious why this mutex imp…
Burrows is also responsible for the Burrows Wheeler Transform, Bigtable, Dapper and Chubby, among others.
The Fastest Mutexes
201–210 of 360 posts
Re: The Fastest Mutexes
#202Earlier quoted context omitted.
When, how, and why. The biggest part of mutexes and how to properly use them is thinking of the consistency of the data that you are working with. Here's a really common bug (psuedocode) if (lock {data.size()} > 0) { value = lock { data.pop() } lock { foo.add(value) } } The issue here is size can change, pop can change, and foo can change in unexpected ways between each of the acquired locks. The right way to write t…
This is one of the areas where Zig's combination of anonymous blocks and block-based defer really pay off. To create a locked region of code is just this { mutex.lock(); defer mutex.unlock(); // Do mutex things } It's possible to get this wrong still, of course, but both the anonymous scope and the use of `defer` make it easier to get things right. Nothing can prevent poor engineering around mutex use though. I'd wan…
Re: The Fastest Mutexes
#203Earlier quoted context omitted.
Are there popular languages that don't have memory models which make reasoning about concurrent models easier? A language with a notion of threading and shared state is going to have something akin to read/write barriers built into the language memory model to tame the beast.
C?
It's C so you don't get a comprehensive set of bells, whistles and horns like the C++ standard library, but the actual model is the same. At a high level it's all the same as C++ 11, the details are not important to most people.
Re: The Fastest Mutexes
#204Earlier quoted context omitted.
APE works through cunning trickery that might get patched out any day now (and in OpenBSD, it has been). Most people producing cross-platform software don't want a single executable that runs on every platform, they want a single codebase that works correctly on each platform they support. With that in mind that respect, languages like go letting you cross compile for all your targets (provided you avoid CGO) is deli…
> Most people producing cross-platform software don't want a single executable that runs on every platform They don't? Having one file to download instead of a maze of "okay so what do you have" is way easier than the current mess. It would be very nice not to have to ask users what platform they're on, they just click a link and get the thing.
Re: The Fastest Mutexes
#205Earlier quoted context omitted.
Wasn't elf format modified by upstream to accomodate for cosmo? That makes it kinda official. Still hard to see a use case for it. If you want everyone to be able to run your program, just write a web app, a win32 program, or a java applet. 20 years old java applets still run on modern JVMs.
A web app is, well, a web app. Many things don't fit this format, e.g. command line tools. A Win32 program will not run out of the box on either Linux or macOS. Neither will a Java app. The nice thing about Cosmopolitan is that it "just works" as far as end user is concerned. But without firm support from the OSes involved, it is inevitably a hack with questionable long-term stability prospects. What we really need i…
Re: The Fastest Mutexes
#206Earlier quoted context omitted.
> For me the biggest challenge when sharing state is that the only benefit I can see for parallelism is performance, so if I'm not gaining performance there is no reason to use parallelism. Aside from performance, another very common reason is to not lock the UI from the user. Even in UI-less programs, the ability to abort some operation which is taking too long. Another is averaging out performance of compute tasks,…
>Aside from performance, another very common reason is to not lock the UI from the user. This is not a good fit for parallelism, this is pretty much always accomplished using concurrency ie. async/await.
Re: The Fastest Mutexes
#207Earlier quoted context omitted.
I was thinking the same. There are many mutexes out there, some are better at certain workloads than the rest. DistributedMutex and SharedMutex come to mind ( https://github.com/facebook/folly/blob/main/folly/synchroniz... , https://github.com/facebook/folly/blob/main/folly/SharedMute... ) Just like hashmaps, it's rarely the case that a single hashmap is better under _all_ possible workloads.
Yeah. I should say, though, that if you're on Windows then I have yet to find a real workload where SRWLock isn't the fastest (provided you're fine with no recursion and with a lock that is word-sized). That lock has made some kind of deal with the devil AFAICT.
https://old.reddit.com/r/cpp/comments/1b55686/maybe_possible...
Re: The Fastest Mutexes
#208Earlier quoted context omitted.
> would be slower than just having everything wait to write to a shared location Nope.
Yup. Message passing has allocation pressure and cache consistency pressure not present in using a shared message location. Especially as the amount of memory in question goes up, the benefit of a shared location increases in terms of the performance impact. Sure, for something silly like writing to an int, there is negative benefit in a shared location, but when you start talking about a dictionary with 1 million en…
With dictionaries, you may have to do a bit of resizing and rehashing at the end. But in my benchmarks, it is still worthwhile.
Re: The Fastest Mutexes
#209Earlier quoted context omitted.
We use spinlocks where appropriate. In the 90s I recall that the general rule of thumb was if the lock is held for The more common pattern in rt/audio code is "try to take the lock, but have an alternate code path if that fails". It's not that is never going to be contention, but it will be extremely rare, and when it occurs, it probably matters. RWLocks are also a common pattern, with the RT thread(s) being read-onl…
These days, fast lock implementations use the following rough idiom, or some idiom that is demonstrably not any slower even for short critical sections. if (LIKELY(CAS(&lock, UNLOCKED, LOCKED))) return; for (unsigned i = 0; i So, the reason to use spinlocks isn't that they are faster for short critical sections, but that they don't have to CAS on unlock - and so they are faster especially in the uncontended case (and…
Re: The Fastest Mutexes
#210Earlier quoted context omitted.
> I'm curious why [Abseil's] mutex implementation is absent from the author's benchmarks. Possibly because it's C++ (as opposed to C)? I am speculating.
> Possibly because it's C++ (as opposed to C)? MSVC 2022's std::mutex is listed, though. (That said, GCC's / clang's std::mutex is not listed for Linux or macOS.) absl::Mutex does come with some microbenchmarks with a handful of points of comparison (std::mutex, absl::base_internal::SpinLock) which might be useful to get an approximate baseline. https://github.com/abseil/abseil-cpp/blob/master/absl/synchr...
I was talking about the wait() and notify_one() member functions for std::atomic. See https://en.cppreference.com/w/cpp/atomic/atomic/wait and https://en.cppreference.com/w/cpp/atomic/atomic/notify_one