Re: Socket Programming

From: Peter Seibel (peter_at_javamonkey.com)
Date: 05/31/04


Date: Sun, 30 May 2004 23:00:05 GMT

David Steuber <david@david-steuber.com> writes:

> Peter Seibel <peter@javamonkey.com> writes:
>
>> As I understand it the point of the C10K page is that at the OS
>> level--at least in mainstream OS's--there's no good solution to the
>> problem of keeping track of which of 10,000 (let alone 100,000)
>> connections may have data to deal with. Unless I'm misunderstanding
>> them there's little that better languages or ways of thinking about
>> writing concurrent software can do to fix *that* particular problem.
>
> I don't think you need to worry about the 100,000 simultaneous
> connection problem. IPv4 supports only 2^16 ports. Even if a process
> could get 100,000 file descriptors, there would be no way for one
> machine to have that many open IP connections. This is actually a
> major reason for the HTTP protocol vs FTP where a typical session is
> much longer. IP connections are a very limited resource.

That doesn't matter to the server. Every connection to a server is to
the same port anyway (typically). It's the client IP-address/port that
makes the connection unique. So while it's true that I can only have
(expt 2 16) connections from a single client IP address, I can have
many, many connections from many, many clients.

> What I got from the C10K page was that the primary problem with one
> thread per connection was running out of stack space. If incomming
> data causes ALL the threads to wake up and then the ones that should
> be idle to go back to sleep (thundering herd), then that would be a
> real problem as well. If you can say ahead of time what the maximum
> stack space you will need is, you should have a way to tell the OS not
> to give you more than that.
>
> However, either way you cut it, time slicing has to be done
> somewhere. Polling is expensive because you are querying descriptors
> that are not ready. The other two methods that were mentioned in the
> article seem like reasonable fixes, but you would still have to do
> some sort of processing on idle connections.

Why? The kernel knows when packets arive on the wire as it is
responsible for decoding them.

> Proper 1:1 threading should work nicely. The ideal case (see sig) is
> that data comes in on the ether and the kernel knows exactly which
> thread to wake up to read it. If the kernel can handle that detail,
> then things are much easier for developers in userland.

Yes. That's called asynchronous i/o. When you issue the i/o call, you
pass along a callback that should be run when the i/o completes. So if
I do a read on a socket, I pass along the code that I want to run when
there is actually data to read. Nothing happens until some data shows
up for that connection.

Which the kernel *does* know since somewhere down in the TCP stack in
decoded the incoming packet and figured out which connection it
belongs to, etc. Of coures I'd also like to keep a thread-like notion
of dynamic context so my special variables, condition handlers, and
restarts are still in place.

(Where is that guy who was writing a TCP stack in Common Lisp? Maybe
he could implement something like this for sockets anyway.)

Actually the question of what the Ultimate Right Thing is is
interesting to me. I seet it as perhaps analogous to an argument I
used to have on a regular basis with one of the other developers at my
last gig: whether a general purpose garbage collector had to *in
principle* less efficient (in computer resources) than manually
managing memory. I had two arguments in favor of GC. The "weak"
argument was that while it might be possible to actually manage memory
more efficiently without GC (by taking advantage of
application-specific knowledge of memory usage patterns) that in
practice it would be so much harder to outperform a good GC
implementation that the programmer using GC would have way more time
to improve the overall efficiency of their program through better
design that it would always outperform a program written using manual
memory management. My "strong" argument was that memory management is
actually complex enough (e.g. you have to consider locality issues,
etc.) that ultimately a good GC implementation would do better on any
reasonably complex application than a human could. (I.e. the same
reason I want my compiler to allocate registers for me.)

So back to threads, there's part of me that would like to believe that
ultimately general purpose threading systems will be so good that the
path to the most efficient program simply will be to spin up as many
threads as you want and let the threading system take care of it.
Analogues to my weak and strong arguments for GC can be made. But I
don't belive that current threading systems have achieved that goal
yet. Not being an OS or virtual machine researcher, I'm not sure what
the open questions are or how near a solution we are. Thus I'm hoping
Luke--who claimed writing super-scalable software is a solved
problem--will answer my other post.

-Peter

-- 
Peter Seibel                                      peter@javamonkey.com
         Lisp is the red pill. -- John Fraser, comp.lang.lisp


Relevant Pages

  • Re: Large virtual memory, small working set
    ... We're basically opening all these connections and receiving data. ... Almost immediately upon starting and loading configuration information, the application starts opening up connections and the memory usage immediately skyrockets. ... The strange thing is - only the virtual memory increases this drastic. ... Is it some sort of side-effect from having that number of open TCP connections that we are stuck with? ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: ZX Spectrum - cant get it repaired - help!
    ... Swapped ROM (not 100% usre if that one works, ... o All 4116 RAM's are 100% ok; all connections were checked, ... sound A and after a second or so, it makes sound B and it keeps sound ... It`s been a long time, but I used to repair Spectrums regularly, and what you describe is symptomatic of one of the memory ic`s being faulty, have you tried it with the 32k extension removed? ...
    (sci.electronics.repair)
  • Re: ZONE_NORMAL memory exhausted by 4000 TCP sockets
    ... The problem is the memory. ... concurrent connections, I know the memory size of ZONE_NORMAL would be ... kernel memory allocation might use twice the ram you intend to use because of power of two alignments. ...
    (Linux-Kernel)
  • Re: ZONE_NORMAL memory exhausted by 4000 TCP sockets
    ... > By configuring ebtables and iptables, an application is running as TCP ... > The problem is the memory. ... > concurrent connections, I know the memory size of ZONE_NORMAL would be ... but other things may consume ram on your kernel. ...
    (Linux-Kernel)
  • ZONE_NORMAL memory exhausted by 4000 TCP sockets
    ... an application is running as TCP ... The problem is the memory. ... concurrent connections, I know the memory size of ZONE_NORMAL would be ... is limited by the capability of the client application. ...
    (Linux-Kernel)