Hacker News new | past | comments | ask | show | jobs | submit login
Swift Atomics (swift.org)
209 points by Austin_Conlon 3 months ago | hide | past | favorite | 37 comments

This is great news. So far I have been using https://github.com/glessard/swift-atomics for projects. It sort of works, have a nice API, but without SE-0282, it is always "try with your own risks" kind of thing.

Just updated https://github.com/liuliu/dflat/ with Apple's atomics. Seems to be just some naming changes from glessard ones (when doing the change), otherwise a pretty smooth transition.

Heh, Foundation intensifies.

Right. Dune also uses that term! https://dune.fandom.com/wiki/Atomics

Basically, whenever i read the word "atomics", in my head it's Patrick Stewart shouting it: https://getyarn.io/yarn-clip/8b3057a8-84ea-44b3-97fe-9e393a3...

Ah! I knew that word was tickling my brain but couldn't figure out why. Thanks for connecting the dots for me!

This is cool. It does address (partly) some of the issues with Swift threading.

That said, I’m not a systems programmer, and basic threads, like those provided by the standard “blunt instrument” approach of standard Swift, will pretty much always give me what I need.

Using threads -especially low-level threads- can lead to a real education in debugging. I only use them when necessary.

> It does address (partly) some of the issues with Swift threading.

FWIW, this is among the first of quite a few concurrency improvements coming to Swift in the near future. Swift 6 is expected to include a real concurrency model, likely based on some combination of async/await and an actor model.

The devs have been actively implementing a prototype [0], and the core team is expected to release a design document/proposal soon [1] [2].

[0]: https://github.com/apple/swift/pulls?q=concurrency [1]: https://forums.swift.org/t/rethinking-async/37984/30 [2]: https://forums.swift.org/t/rethinking-async/37984/51

> Using threads -especially low-level threads- can lead to a real education in debugging.

Oh yeah it can. I'm still scarred by an error that took me a month to solve: I was self-teaching pthreads and kept getting an access violation with a stack trace starting at 0x0.

The only bug that ever beat me in my two decades coding was in a custom lock free data structure using an early version of c++11. I spent a month on it, including writing custom visualization and logging tools, but I never found the issue that caused a crash once every few hundred billion operations.

Later I saw some suspicious compiler bug fixes around compare and swap, and I still wonder if that was maybe it.

I read that some lock free libraries needed to be updated when Apple released it's first dual core ARM processors. Something about ARM's read or write ordering guarantees are looser than Intels.

Me I'd rather roll my own cryto than try and write my own lock free data structure.

Yes, this is something where different CPU architectures do it differently, even between ARMv7 and ARMv8 etc. There's a great presentation on the differences here:

https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-20... https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-20...

He goes into the details of ARM vs Intel etc in the middle of part 2, but really part 1 is well worth a watch.

Fun fact: Apple's recent processors have a mode where they emulate stricter ordering guarantees (for Rosetta, of course).

That reminds me I think I saw some blurb in an MCU data sheet that mentioned the processor can do out of order memory accesses which if you're an embedded guy tends to freak you out. However the chip designers disabled that for peripheral memory accesses.

Which is very nice of them.

1 in every hundred billion... is that low enough odds to be cosmic rays?

A hundred billion operations is spinning on a loop for a couple minutes, so not really.

It took about ten minutes at full system utilization on all cores, running the "torture test" in a loop in each thread.

For a cosmic ray bit-flip, or to perform a hundred billion operations?

One hundred billion operations. The machine didn't have ECC memory, so a bit flip is a possible explanation. I should have checked if it was reproducible with ECC.

I still think a logic bug or compiler bug was at fault though.

Obligatory sometimes, just sometimes, it is the compiler.

It does, but like the article says this is generally not something you want to be touching. The number of users of this API is likely to be very small, for the rest Grand Central Dispatch is what you should probably reach for.

This is true, but every non-trivial app requires the equivalent of `std::atomic_flag` and `std::atomic<int>` at some point...

Not really. If you don’t mind having the absolute best performance, normal queues and locks work just fine.

Question to anyone more knowledgeable about swift, why does it recommend against using atomics? It makes a joke about thread sanitizer, but what actual steps do you have to go through to use atomics in swift safely?

They're surprisingly difficult to use correctly, especially if you're trying to build something clever like lock-free data structures.

Atomic access can use relaxed memory ordering, meaning that values don't actually change immediately for all threads. There are subtle rules about what changes the hardware and the optimizer can delay and reorder. It's like playing chess with threads.

There's also a common pitfall that x86 hardware has more consistent and forgiving behavior than the spec for atomic operations. Broken atomic code may appear to work fine on x86, but fall apart on ARM.

Not all ARM CPUs even, there's a wide range between those using the relaxed memory model in the spec, some server CPUs having TSO (roughly matching x86) and others having sequential consistency (NVIDIA in-house CPUs).

The same as in any language, really. The problem is that some developers assume "atomics == thread safe, so I'll make an easy way to mark things as 'atomic' and I won't have to worry about it."

That's why the standard advice on iOS and macOS was to mark properties as explicitly `nonatomic` – because it was almost never the right tool for the job.

Sorry for my ignorance, but: why isn't atomic == threadsafe?

Just a guess. Individual variables may be atomic, but that doesn't guarantee that a series of operations over one or several of them is thread safe.

Thus it's likely that a developer using atomics still makes mistakes, and yet they get a false sence of safety.

This is in the context of properties in ObjC, which will synthesize accessor methods for the developer. If the property is marked `atomic` (which is also the default), the getter and setter will share a mutex. The mutex makes reads and writes effectively "atomic" -- gets and sets on different threads will never interrupt one another.

But that's all you get. And the catch is that there's usually more you need to do to guarantee thread safety for a particular operation.

For example, `@property (atomic) NSMutableArray *array;` has no guarantees about appending or removing the array's _contents_.

For another example `@property (atomic) NSUInteger count;` is a mildly subtle trap, because a statement like `self.count += 1;` is _not atomic_. It's an atomic read, an increment, and an atomic write. You need another synchronization mechanism to make the whole update threadsafe.

If you’re prepared and willing to learn much more about atomic operations than you ever thought you would, there’s no substitute to Herb Sutter’s classic talk ”atomic<> Weapons” from C++ And Beyond 2012 [1].

[1] https://www.youtube.com/watch?v=A8eCGOqgvH4

Atomic are low-level concurrency primitives; often a mutex is all you’ll ever need and they’re much easier to reason about.

Hmmm, not a Tom Swift enterprise BTW.

I had the same thought and was reminded of how old that makes me.

Those books were corny as hell but the fact that the hero saved the day with his wits made an impression on me as a young lad.

Yup, I thought this was a new reactor design.

What about webassembly?

What about it?

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact