-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Could a byte stream read directly into and out of a SAB (w/o transfer)? #757
Comments
There was some discussion of SAB with streams previously here: #495 (comment) It seems likely that we will add a way to use a SAB without transferring. Unfortunately it doesn't look like we will get the nice memory protection semantics that would let us avoid data races. I'm not concerned about exposing data races to wasm, since C++ programmers already live in a world of races. I feel it's unfortunate to expose it to Javascript. |
Ah, I see, so should I keep this issue open for this specific request or is it a dup of #495? |
I think this is useful as a separate issue. I've marked it with Milestone V2 to reflect that it's not something we'll be changing immediately. |
I think we should change this sooner rather than later. In Blink we're behind on implementing byte streams, but others have done so, and should be able to get these benefits---especially if we have interested consumers in the wasm space. Plus, I believe right now the spec is incoherent, as it tries to transfer SharedArrayBuffers, which causes a spec-level assert failure. I do think it's sad that this exposes data races, but I also agree that SharedArrayBuffers in general broke that seal, and we should integrate with them rather than wishing they didn't do that. I'll try to work on this when I get done with TC39 and some other work items... |
If in future we'd like TextEncoderStream's I think all solutions involve adding an extra copy when the output is a SharedArrayBuffer. The question is whether this copy becomes part of the ReadableStream machinery that is specified by a flag, or whether the underlying source has to detect that |
Talking to @vasilvv today in the context of WebTransport using whatwg streams and how that kind of use case could perform optimally when used with wasm: in addition to the advantages identified above, the new API could potentially use a callback design (instead of promises) where the SAB-view and callback were registered once and then reused throughout the duration of the stream, so that there was, by design, without engine heroics, zero garbage generated per packet/chunk. |
I don't think we're likely to add callback-based APIs. Eliminating the promise from the external API wouldn't eliminate the promise returned from pull(), nor the other objects that are created internally. The objective of "zero garbage" isn't achievable without engine heroics anyway, so I don't see a compelling reason to add APIs that don't align with the rest of the standard. |
From what I've heard from @vasilvv, there's a lot of overhead with the current approach, enough to be problematic for APIs considering using them, so perhaps more cross-cutting changes could be justified with the goal of not creating garbage on each chunk, given that performance is the point of the lower-level API. |
I think the root cause here is not that promises are slow per se, but rather that there are too many of them. If we switch to callbacks, we will probably just run into the problem of the callback being called too often. I am actually not sure I understand the proposal here. I can see two things we can do with SABs:
The description in the issue seems to indicate that (1) is proposed, but the |
FWIW, I did some prototyping to try to benchmark this before streams were standardized: https://blog.wanderview.com/blog/2015/06/19/evaluating-streams-api-async-read/ I'm sure there are a lot of problems with what I did, but I think the conclusion was that promises were no worse than callbacks in the end. So I suspect you are correct better chunking is the answer. |
I'm not sure those two are in conflict. (1) is what the proposal in this thread is, in that it has observable effects on the developer experience of using streams. (Object identity gets preserved, which is easier to work with than having to constantly switch what Indeed, I think (2) is maybe doable even with the current spec, with just normal The only tricky thing I can imagine is that the contents of the AB/SAB need to only visibly change to JavaScript at well-defined points (essentially, after |
I've been thinking about this a bit more, and I have an idea. I propose adding an extra option to The reason for disabling detaching the buffer even when it is not shared is for the convenience of wasm programs which would like to be able to use part of their memory as a buffer without losing access to the rest of it.
JavaScript underlying sources mostly won't need to pay attention to the For underlying sources implemented as part of the platform it is far more serious. When implemented in C++, we don't even know beyond doubt that we can safely If we do this we should also rethink the enqueue algorithm called by other standards to be safe-by-default. |
Hmm. I think the idea of What motivates the desire to let the safety vary independently of the type, for this particular web platform feature? Note that wasm memory can be made shraed using |
It would be really great if wasm could read from a stream directly into its memory. The backing
ArrayBuffer
of aWebAssembly.Memory
cannot be detached (nor would you want to since it holds the general program state needed for execution in the meantime) so what would be great is if the caller of a read or write could pass a typed array view of a buffer that is not detached. For a regularArrayBuffer
, this would mean some additional copying to avoid races. However, if the buffer is aSharedArrayBuffer
, then perhaps it would be fine to expose the races (and no worse than anything else with SAB).As an additional benefit, I think the implementation of "read into a view" from a file-backed stream could use
mmap
to make a copy-on-write mapping of the file directly into the target memory.(cc @flagxor)
The text was updated successfully, but these errors were encountered: