Le 27/04/2013 19:30, Patrick Walton a écrit :
On 4/27/13 4:06 AM, David Bruant wrote:
I believe too this is doomed to happen. Firefox is under a huge struggle
to remove as much as sync IO code as possible as part of the Snappy
effort [1].
This is a completely misleading comparison. Firefox's sync I/O *blocks
the entire main thread of the browser*, freezing up the UI in the
process. That's why Firefox is removing it. Firefox doesn't have
lightweight green threads. And Servo doesn't even have a "main thread".
True.
Tasks provide something easier to use than threads, so a
browser in Rust can make things snappier by moving things to tasks, but
allocation, de-allocating and scheduling have a cost.
There is a plan to cache aggressively, to avoid allocation and
deallocation of stacks. Scheduling is very quick, just a context
switch in userspace.
Still, one stack per I/O operation has a bad smell to it. Being forced
to create a new task (even if "only" 2k) because the 49000 previous ones
are sitting idle doesn't sound right. Not contacting the remote resource
(disk, network) would be worse. To do efficient IO, there got to be a
cheap way to start an IO and wait for it. Creating a task, doesn't sound
cheap enough to work at scale.
I don't see any reason why not; the overhead of one userland context
switch seems minuscule to me compared to the overhead of doing the
I/O. Have you done benchmarks?
I haven't. However, what I've read in this message and a couple of
others [1][2] about the cost of tasks makes me more optimistic than I
initially was.
I'd like to encourage everyone reading to take the time to watch [2] (at
least 10-15mins starting where I linked to).
If you're going to count allocation and deallocation of stacks against
Rust's model, then why not count the allocation and deallocation of
the callback closures and associated environments in node.js' model?
It is *not* the case that node.js I/O allocation-free, as you're
implying.
I'm was implying that sorry for the confusion. I'm not a libuv and
Node.js expert, but I believe it could take as few as a file descriptor,
a reference to the function to call when the request comes back and a
message slot in the event loop message queue.
The closure cost doesn't count as it's application memory. A Rust
program would have an equivalent cost (forgetting that JS doesn't have a
control on memory as efficient as Rust)
In any case, the few things I enumerated don't seem to compare to the
2k/4k that's apparently necessary for a new task stack.
I think the cost of tasks can be made only marginally bigger than an
event loop if tasks are created lazily (which I believe is what is
suggested in [2]). Creating them lazily would require a "queue" of tasks
to create and run which would be the moral equivalent of the message
queue in the event loop.
If you're carrying around state per I/O request, and you have an
unbounded number of I/O requests that can be in flight, you must incur
an allocation to store that state. Whether that's part of a callback
or part of a task's stack, it has to happen.
Definitely. The point I was trying to make is that the current cost
(2k/4k) seems disproportionate by comparison with what's needed in
theory while waiting for an I/O request to come back (a file descriptor
and a pointer to the function to call)
Thanks for your answer,
David
[1] https://mail.mozilla.org/pipermail/rust-dev/2013-April/003829.html
[2] https://mail.mozilla.org/pipermail/rust-dev/2013-April/003837.html
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev