Why stackless (async/await) for Swift?

the typical set of trade-offs associated with various thread implementations is:

(Edited to include iOS memory limitation)

  1. no multi CPU support out of the box for lightweight threads
  2. real threads don't scale (but that's not your concern with fibers)
  3. virtual address space issue for stacks (but that's not a problem on 64 bit systems)
  4. wired memory space is still an issue for stacks
  5. cache unfriendliness on context switches
  6. stack switching is easy to do in a library and C/C++ friendly. stack copying is no go for C/C++ inter-op, leads to more expensive stack switching and needs compiler support.
  7. Edited: iOS VM limitation of 5GB (unless overridden on iOS15+ on supported devices, see com.apple.developer.kernel.increased-memory-limit for details)

let's only talk about switchable stacks implementations here.

let's say you allocate 2GB of VM space for stacks. questions arise: what is your stack size? do you manually control it upon fiber creation? can your function recurse enough to cause stack overflow? remember that every time you call into OS it uses an unspecified amount of stack which is hard to predict or guarantee, so better be safe than sorry. let's say you allocate 100K VM space per stack and your functions won't overflow the stack - that will give you a hard limit of 20K stacks on a 32 bit platform. let's focus on 64 bit platforms only, so this aspect is not a problem. 2GB is nothing there, but you have to wire at least one page size of RAM per fiber, probably more. page size was 4K in the past now i believe it is 16K (on A9). let's optimistically assume that you only wire 16KB per fiber. how much wired memory your app can use (for stacks only leaving some space for anything else)? let's say 1GB for stacks (and perhaps 1GB for anything else). at 16K per fiber that's a 60K fibers limit.

all in all, if you only need a 100 or a 1K or even 10K of lightweight threads - fibers are totally fine. scaling to 100K is problematic. that's from someone who knows a thing or three about threads since ThreadLib and Thread Manager on System 7 days :wink:

having said all that - have you considered to go the opposite way, to promise based solutions? no compiler support is needed and most of the above issues just do not exist. or is it a no go due to C/C++ inter-op requirements?

1 Like