> Lets say you have 20 threads. You improved performance 20 times, so the rate is now 4 request per second. Still, way too small. You can keep throwing threads at the problem, but threads are expensive in terms of memory usage and scheduling. I doubt you’ll ever reach hundreds of requests per second this way. Let's say I'm using Java instead of Python. Lets say I use a lot more threads than 20. I will reach thousands…
Something I'd like people to understand, at a very deep level: event-based async programming, and blocking thread-based programming, are fundamentally the same. The problem of maintaining your state in between event triggers is explicit in the first style; it's implicit, in the thread stack and CPU instruction pointer, in the second style. In the second style, it's the OS which is running the event loop, and it dispa…
Understanding the code inside Tornado, the asynchronous web server
31–40 of 43 posts
Re: Understanding the code inside Tornado, the asynchronous web server
#32Earlier quoted context omitted.
Something I'd like people to understand, at a very deep level: event-based async programming, and blocking thread-based programming, are fundamentally the same. The problem of maintaining your state in between event triggers is explicit in the first style; it's implicit, in the thread stack and CPU instruction pointer, in the second style. In the second style, it's the OS which is running the event loop, and it dispa…
That's essentially the thesis of this 1978 paper, though they group evented programming under the broader "message-passing" style: http://www.sics.se/~adam/pt/duality78.pdf
Re: Understanding the code inside Tornado, the asynchronous web server
#33Earlier quoted context omitted.
> On a nonblocking socket, the I/O operations you're talking about are simple u/k and k/u buffer copies. But because there is an IO mode where these copies are done by the kernel when data arrives not by the user process (after a kernel notification), there is now a differentiation between blocking and asynchronous. Asynchronous refers to IO readiness notifications, "blocking" refers to the copying of data (the actua…
I don't believe that "blocking" refers to the copying of data. I don't believe that a process can be "blocking" and "running". Where are you getting this from?
Yes, if aio_* system was never invented, we wouldn't be arguing, but because it exists it introduces a new possible way of doing IO. It is a general enough way of doing IO and at hardware level we have DMA but in the land of syscalls we have aio_.
Ok, just curious, what words would you use to describe what aio_ calls do?
Over the years many have thought of a way to bring that style of IO to networking. So far it works for disk IO very well. For example take a look at this benchmark from lighttpd for a sendfile:
http://blog.lighttpd.net/articles/2006/11/09/async-io-on-lin...
It looks like there is a consistent 50% improvement in speed when using aio with a 1MB block.
Wouldn't it be nice to have that kind of improvement for network sockets as well? I think it would be and there have been many attempts over the years but nothing good yet has happened.
Re: Understanding the code inside Tornado, the asynchronous web server
#34Earlier quoted context omitted.
I am not talking about in-kernel hardware mechanisms like DMA and such. Or about memory mapping a file. It is about the system call interface to perform IO. Yeah, I guess you can call it memory-mapped but I don't think that is quite accurate in this context.
The system call interface to perform I/O cannot be described as "memory mapped"; the read/write system calls are programmed I/O. The opposite of memory mapped. You're letting terminology get you into trouble. You should just let go of your definitions and make the broader point you're trying to make, which might still be salvageable.
Re: Understanding the code inside Tornado, the asynchronous web server
#35> Lets say you have 20 threads. You improved performance 20 times, so the rate is now 4 request per second. Still, way too small. You can keep throwing threads at the problem, but threads are expensive in terms of memory usage and scheduling. I doubt you’ll ever reach hundreds of requests per second this way. Let's say I'm using Java instead of Python. Lets say I use a lot more threads than 20. I will reach thousands…
Even with Python (CGI backed by Apache), you can scale with threads. The issue of scaling with threads vs. events is a pretty hot debate, and I think the author sets up this kind of criticism by addressing it poorly. Personally, I fall into the event-driven camp, because it involves the operating system as little as possible (only file descriptors). The C10K link has a great overview of the threaded approach ( http:/…
Re: Understanding the code inside Tornado, the asynchronous web server
#36> Lets say you have 20 threads. You improved performance 20 times, so the rate is now 4 request per second. Still, way too small. You can keep throwing threads at the problem, but threads are expensive in terms of memory usage and scheduling. I doubt you’ll ever reach hundreds of requests per second this way. Let's say I'm using Java instead of Python. Lets say I use a lot more threads than 20. I will reach thousands…
Re: Understanding the code inside Tornado, the asynchronous web server
#37In an event based system the overhead for each connection is at least three orders of magnitude lower, sometimes four or five (hope I'm remembering this right). This translates into _considerable_ increase in number of connections that can be handled simultaneously, not quite the equivalent number of orders of magnitude due to other aspects of the system becoming more of the bottle-necks, but still dramatic.
This was a data-driven observation, not conjecture or assertion. I listened in during a break while the nodejs guys argued about approaches to getting TLS working better - they were worrying about the 1MB overhead for a TLS connection because that's a significant percentage of a connection handler. Think about that for a minute in the context of an apache threaded instance. 1MB matters? wow!
I'm new to this area and this was very interesting stuff and seemed related to the various discussions below about a threaded system can do what an event based system can do.
Re: Understanding the code inside Tornado, the asynchronous web server
#38Earlier quoted context omitted.
I don't believe that "blocking" refers to the copying of data. I don't believe that a process can be "blocking" and "running". Where are you getting this from?
I guess "blocking" is overloaded here. To me it refers to the process of performing IO, but you think about process states from the point of view of the scheduler (as in RUNNING state vs BLOCKING (or IOWAIT)). Yes, if aio_* system was never invented, we wouldn't be arguing, but because it exists it introduces a new possible way of doing IO. It is a general enough way of doing IO and at hardware level we have DMA but…
Re: Understanding the code inside Tornado, the asynchronous web server
#39Earlier quoted context omitted.
Even with Python (CGI backed by Apache), you can scale with threads. The issue of scaling with threads vs. events is a pretty hot debate, and I think the author sets up this kind of criticism by addressing it poorly. Personally, I fall into the event-driven camp, because it involves the operating system as little as possible (only file descriptors). The C10K link has a great overview of the threaded approach ( http:/…
Another issue with evented frameworks in python is that you have to ensure nothing is blocking anywhere in your code, which becomes harder the more complex your application becomes. People will often mention IO, database, etc... forgetting that it is also an issue if your request handler takes CPU for N ms (e.g. encoding a relatively large payload in json, etc...). everything needs to be written with async in mind. L…
Re: Understanding the code inside Tornado, the asynchronous web server
#40Earlier quoted context omitted.
I don't believe that "blocking" refers to the copying of data. I don't believe that a process can be "blocking" and "running". Where are you getting this from?
I guess "blocking" is overloaded here. To me it refers to the process of performing IO, but you think about process states from the point of view of the scheduler (as in RUNNING state vs BLOCKING (or IOWAIT)). Yes, if aio_* system was never invented, we wouldn't be arguing, but because it exists it introduces a new possible way of doing IO. It is a general enough way of doing IO and at hardware level we have DMA but…