Tuesday, August 6, 2019

Practical Concurrency: Some Rules

Mark Bernstein:

You can get away with murder. Going by the book, you’ve got to use extreme caution and you’ve always got to get it right. In practice, Tinderbox Six took all sorts of risks and accepted that it was Doing It Wrong in order to get stuff done.

It sounds like there’s a good story here. My experience has been more that it’s sometimes hard to know when you’re doing something wrong, but that once you’re aware of it it’s not that much extra effort to do it by the book. I try to do that as much as possible because it’s no fun tracking down concurrency-related bugs.

The profiler is now good. It wasn’t always. In the Tinderbox 4 era, firing up the Profiler meant recompiling the world, and that took 20 minutes. Then, you'd get slow and inconclusive results, and throw up your hands. Life today is better[…]

The profiler is indeed really great—when it works. Unfortunately, I have not had much luck getting it to work with tests. Most of the time, I Control-click on the test diamond and choose “Profile ‘testName()’”, it recompiles and launches Instruments, but it doesn’t actually run the test code. Sometimes I can get it to work with the old and clunkier approach of stopping at a breakpoint and then attaching Instruments to the running process, but other times it doesn’t actually record what it’s supposed to.

If a queue has one clear purpose, it’s easier to be confident it won’t deadlock. Dispatch queues are cheap. Don’t share queues, don’t reuse queues, don’t worry about making queues.

Classes should encapsulate their queues.

Update (2019-08-07): Thomas Clement:

Queues are not cheap, you should reuse queues, you should worry a lot about making (too many) queues.

He’s posted some libdispatch efficiency tips and links to some good threads from Swift Evolution. You may find them easier to read in the new Swift forums:

Although some of the messages seem to have been imported out-of-order.


Update (2019-08-08): Marcel Weiher:

From a, cough, well-respected, cough, performance book:

In the end, I’ve rarely had to use multi-threading for speeding up a CPU-bound task in anger, and chances are good that I would have made my code slower rather than faster.

... The advice to never optimize without measuring as you go along goes double for multi-threading.

2 Comments RSS · Twitter

« Often, the easiest approach remains serial access managed by a single dedicated serial queue that can be used with the read sync/write async rule. »

Can’t remember which (recent) WWDC session talk about it, but don’t use the sync/async pattern. Making all your access sync is faster as it can trigger « thread switch elision » optimization.

[…] Practical Concurrency: Some Rules […]

Leave a Comment