Return-Path: Delivered-To: apmail-httpd-dev-archive@www.apache.org Received: (qmail 90933 invoked from network); 13 Oct 2005 18:25:26 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 13 Oct 2005 18:25:26 -0000 Received: (qmail 40881 invoked by uid 500); 13 Oct 2005 18:23:47 -0000 Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 38304 invoked by uid 500); 13 Oct 2005 18:23:33 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 37449 invoked by uid 99); 13 Oct 2005 18:23:24 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 13 Oct 2005 11:23:24 -0700 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: neutral (asf.osuosl.org: local policy) Received: from [204.146.167.214] (HELO Boron.MeepZor.Com) (204.146.167.214) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 13 Oct 2005 11:18:21 -0700 Received: from [9.27.38.32] (dmz-firewall [206.199.198.4]) by Boron.MeepZor.Com (8.12.8/8.12.8) with ESMTP id j9DIHShe017300 for ; Thu, 13 Oct 2005 14:17:48 -0400 Message-ID: <434EA46F.9000509@apache.org> Date: Thu, 13 Oct 2005 14:16:15 -0400 From: Greg Ames User-Agent: Mozilla Thunderbird 1.0.6-1.4.1 (X11/20050719) X-Accept-Language: en-us, en MIME-Version: 1.0 To: dev@httpd.apache.org Subject: Re: async write completion prototype References: <434A11BC.5080406@force-elite.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Brian Pane wrote: > On Oct 10, 2005, at 12:01 AM, Paul Querna wrote: >> If the content has already been generated, why add the overhead of >> the context switch/sending to another thread? Can't the same event >> thread do a non-blocking write? >> >> Once it finishes writing, then yes, we do require a context-switch to >> another thread to do logging/cleanup. >> >> I am mostly thinking about downloading a 1 gig file with the current >> pattern against a slow client. A non-blocking write might only do >> ~64k at a time, and causing 1 gig/64k context switches, which seems >> less than optimal. > > > If I had to choose, I'd rather do the context switches than devote a > thread (and the associated stack space) to the connection until > the writes are finished--especially if the server is delivering a > thousand 1GB files to slow clients concurrently. > > However, it's probably possible to have _both_ a high ratio > of connections to threads (for scalability) and a low ratio of > context switches to megabytes delivered (for efficiency). > The Event MPM currently has to do a lot of context switching > because it detects events in one thread and processes them > in another. If we add async write completion to the > Leader/Followers MPM (or incorporate a leader/follower > thread model into Event), it should reduce the context > switches considerably. this is interesting to me because Brian Atkins recently reported that the event MPM was much slower. http://mail-archives.apache.org/mod_mbox/httpd-dev/200509.mbox/%3c43219161.3030102@web.turner.com%3e it would be nice to hear more details, but I assume that this means event is burning more CPU for a given workload rather than some kind of extra latency bug. we know that event has more context switching than worker when keepalives are in use but pipelining is not, and async write completion will add to it. I suppose we should profile event and worker and compare profiles in case there's some other unexpected CPU burner out there. if context switch overhead is really the culprit, how do we reduce it? if I recall correctly, leader/follower sort of plays tag and the next thread that's It gets to be the listener. I can see that running the request processing on the same thread that does the accept would be more cache friendly, and it might save some of the current queuing logic. but doesn't this have about the same amount of pthread library/scheduler overhead to "tag" the new listener and dispatch it as we have now waking up worker threads? another brainstorm is to use a short keepalive timeout, like 200ms*, on the worker thread. if it pops, turn the connection over to the event pollset using the remaining KeepAliveTimeout and give up the worker thread. Greg *200ms - the idea is to use something just big enough to cover most network round trip times, so we catch the case where the browser sends the next request immediately after getting our response.