Live data from Hacker News

The Fastest Mutexes

justine.lol

201–210 of 360 posts

Re: The Fastest Mutexes

#201
post #36
post #2

> 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.

Also a really nice person. And funny.

Re: The Fastest Mutexes

#202

Earlier 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…

This doesn't seem to add anything over and above what std::mutex in C++ or a synchronized block in Java offer?

Re: The Fastest Mutexes

#203
post #186

Earlier 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?

C has the same model as C++ from the same era, so C11 is the C++ 11 model, C23 is C++ 20 and so on.

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

#204

Earlier 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.

[deleted]

Re: The Fastest Mutexes

#205

Earlier 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…

Yes that's exactly what we need. And we'll be laughing to the bank when we bundle a browser toolbar with adware into its installer ten years down the road. Oh wait Java already did this. OTOH Cosmopolitan gives you complete autonomy. You don't need a JVM to run a simple native command line program on multiple OSes and I proved that.

Re: The Fastest Mutexes

#206

Earlier 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.

Assuming that the APIs & libraries that you need are async. Which is, unfortunately, not always the case for historical reasons.

Re: The Fastest Mutexes

#207
post #95

Earlier 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.

The downside of the deal with the devil...

https://old.reddit.com/r/cpp/comments/1b55686/maybe_possible...

Re: The Fastest Mutexes

#208
post #123

Earlier 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…

You are talking about writes to a data structure such as a list or a dictionary from multiple threads. Nobody uses advanced message passing techniques for that. A list is basically the poster child of why you avoid mutexes: each thread writes to its own version of a sublist, with no use of mutexes, and then at the end of the processing every thread's lists are merged together. Merging a list takes O(1) time by manipulating a few pointers. You avoid mutexes and there's zero drawback. I don't know why you are talking about copying or allocating: a list requires no copying to be merged, and in this case all the allocations still happen over multiple threads so there's no change in allocation pressure. If your allocator is bad, there could be internal mutexes inside the allocator, but that's besides the point.

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

#209

Earlier 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…

[deleted]

Re: The Fastest Mutexes

#210
post #175
post #54

Earlier 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...

std::mutex is rarely used. In libc++ for example it was just pthread_mutex_t. So it's not different from just benchmarking pthread.

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

Post reply on HN