Le 26/04/2013 23:23, Brian Anderson a écrit :
On 04/25/2013 10:42 PM, james wrote:
On 24/04/2013 23:38, Brian Anderson wrote:
What I am focused on now is the design of a synchronous API for
sending and receiving streams of bytes, along with an implementation
built on an internal *asynchronous* I/O interface attached to the
scheduler event loop. This includes reading and writing files, TCP,
UDP, Unix sockets, stdio, pipes, adapters for string parsing,
compression, memory buffers, etc.
This always concerns me - the design will tend towards having state
on the stack etc and 'pull' processing rather than focussing on a
clean design for a chain of state machines that handle 'push' of data
coming from AIO completion events.
Now I know that with say Erlang this is less concerning because
processes are very lightweight there and you have process-specific
GC, and I guess Rust has an ambition to be like that - but is it
ready to handle this sort of IO framework in that way?
I share your concern. It's likely that Rust tasks will never scale as
well as Erlang and I suspect that we will ultimately want an async API
that does not impose the expense of 1 task per I/O stream.
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]. 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.
Specifically, will your IO framework be practical with 50,000
connections in reasonable memory (say a constrained 32 bit process)
I do think 50,000 I/O-performing tasks in a 32-bit process is within
our reach. Last year I demonstrated 500,000 simultaneous Rust tasks
(that did nothing but wait) in a 32-bit process, but there have been
severe regressions since. On Linux I think we can get the initial
allocation overhead for a single task into the ~2k range for sure.
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'd like to encourage everyone reading to take the time to watch [2] (at
least 10-15mins starting where I linked to).
Graydon Hoare wrote:
If you want code to interleave, you put it in separate tasks. That
should be efficient enough to be practical.
I believe it will be practical, but it imposes an unnecessary burden in
the face of lots of concurrent I/O.
If it's not, the task model is not useful.
I completely disagree. I've been working with Node.js for a year and a
half now and non-blocking I/O makes my (single process) code fast enough
by default so that I've never had to worry about it.
My use case is that I'm writing a crawler service. It receives requests
from the network, crawls a bunch of pages and sends back the result.
There is some computation due to HTML parsing, finding links, etc. The
single-threaded version is cool, but exploiting the X (often 4, but
maybe 8 one day) cores in the production machine is super nice too. The
service becomes X+1 process. One receives orders, delegates to the X
actual crawlers and answers. The X other crawlers do the actual work.
2 things that were/are annoying in making my crawler service parallel:
1) In Node.js, you have to fork and create a new process to get
parallelism. In Rust, create a task and you're done. A process is more
heavy-weight than a task.
2) Communication between 2 things that run in parallel (process)
requires copying memory. Inefficient as hell by comparison with Rust and
communication with unique pointers.
Even with single-threaded interleaving in Node.js, I envy the Rust task
model as it makes parallelism both easy and efficient.
My point here is that the task model is useful even if interleaving can
happen within a task.
David
[1] https://wiki.mozilla.org/Performance/Snappy
[2] https://www.youtube.com/watch?v=M-sc73Y-zQA&#t=289s
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev