stack-switching icon indicating copy to clipboard operation
stack-switching copied to clipboard

Do we really need this added complexity?

Open trusktr opened this issue 3 years ago • 8 comments

I have an example Promise implementation in AssemblyScript that can be compiled to either JavaScript (with TypeScript compiler), or to WebAssembly (with AssemblyScript compiler), here:

https://github.com/aspkg/ecmassembly

In particular, here's a test:

https://github.com/aspkg/ecmassembly/blob/5d8811fae1ea99c7d67cbacb32832d7033b1142c/example/assembly/index-wasm.ts#L124

This is done by simply using a single binding from the host for scheduling:

https://github.com/aspkg/ecmassembly/blob/5d8811fae1ea99c7d67cbacb32832d7033b1142c/index.js#L50

See also setTimeout, requestAnimationFrame, etc.

trusktr avatar Jul 17 '22 23:07 trusktr

Since I am not personally familiar with AS it is hard to be sure how to interpret this. However, you may be under a mis-apprehension about the intended audience for JS-Promise integration. It is not really aimed at folk writing 'new' code; but rather at pre-existing modules (typically written in C/C++) that were written to use synchronous APIs. Imagine porting 10MLOC+ written in C to WebAssembly that was originally written using read, not read_async. Similarly, for core stack switching, the primary issue is to permit languages that already manage their own tasks (e.g., event loops, threads and generators) to have a performant way of doing so. Such languages can already do the equivalent of your example, by using tools like asyncify which implements a so-called CPS transform. However, the effect of that transform on code size (*2-*3) and performance (50%-10%) make that route difficult to justify.

fgmccabe avatar Jul 18 '22 18:07 fgmccabe

What's the indented goal for this which is different from the stack_checkpoint and stack_restore functions which are part of the wasix spec?

The only main difference that I see is that you want better debug-ability than those functions offer
What's the reason you want this as a whole new feature, rather than improving on/extending the existing stack control functions which have already made it into runtimes?

AjaniBilby avatar Feb 12 '24 00:02 AjaniBilby

The stack switching effort aims primarily at a standard-compliant implementation of features like these. In addition, the use cases for stack switching go beyond longjmp/setjmp; some of which are quite performance sensitive: e.g., yield-style generators and green/virtual threads.

fgmccabe avatar Feb 12 '24 16:02 fgmccabe

Cooperative multi-tasking can be achieved through a dequeue of long-jump addresss + stack pointer, and as you can't store arbiarty data on the wasm stack, and instead you need to manage a virtual call stack in linear memory - I'm not sure what the extra control of the wasm stack actually enables, over the stack_checkpoint/stack_restore since the majority of the stack is already client code managed.

The main benifits I could see from it being part of the language is enabling the implementation of preemptive multitasking because you have enhanced stack control, allowing for binding interrupts that jump to a certain stack point. But from my understanding of this feature it doesn't seem like it's the goal.

With just a long jump and stack stashing (checkpoint/restore) you can implement coroutines without having to do stack splitting like LLVM, which seems to be the main thing you're trying to avoid. If you have coroutines then you have generators, and if you have generators you can implement async functions with only a small amount of runtime code.

To be clear, I'm not against the proposal, I'm trying trying to find the portion of the vendiagram where stack-switching and wasix stack-checkpoint/restore don't overlap, because right now it seems to me like they're functionally equivalent, it's mostly a difference of implementation detail, which could of course help reduce binary size which is a goal of wasm.

AjaniBilby avatar Feb 12 '24 22:02 AjaniBilby

Are you aware that there are actually two proposals for stack switching?

fgmccabe avatar Feb 12 '24 23:02 fgmccabe

If it helps, https://github.com/WebAssembly/stack-switching/blob/main/proposals/fibers/Explainer.md is more or less an extension of what you're proposing, with only some smaller extra additions to support richer control flow for things that can't quite be reduced to those (at least without a lot of boilerplate).

dead-claudia avatar Feb 12 '24 23:02 dead-claudia

I was more replying to exactly what you were saying here, rather than what has written out with a lot more care in the repo. These proposals are only in phase one, so I'm defintly digging to deep into the exact details since they could change depending on the implementation of the proposals before it.

My main fear with both of the proposals is the specification becoming bloated because of the level of overlap with existing and proposed features, and that some of the specific instructions proposed seem more like nice to have short hands for what could been a lower level more versatile feature which would then be slightly more verbose to use.

There are a lot of specifications for all sorts of things which have added nice to have short hand features, which have then ended up in use case nightmares because of later miss-use/overuse or slight implementation variance between vendors. But I'm also probably being a bit too over cautious

AjaniBilby avatar Feb 12 '24 23:02 AjaniBilby

In fact, my preferred approach is documented here. Even simpler than the fibers approach.

fgmccabe avatar Feb 13 '24 01:02 fgmccabe