Has anyone noticed any speed differences for epoll? It seems to slightly slow down my app, but I''m not sure if it''s epoll problem or not. "normal" tests seem to take the same speed, but not multi threaded scripts. Also with kqueue I believe there may be something wrong with the implementation, as when using it for some reason about 4/5 connections are immediately unbound when connected from one machine to itself. Select works well though. May be related to http://rubyeventmachine.com/ticket/5 It''s not mission critical since my production app will be linux, not mac os x, but thought I''d mention it. Thanks! -R
> > Has anyone noticed any speed differences for epoll? It seems to > slightly slow down my app, but I''m not sure if it''s epoll problem or > not. "normal" tests seem to take the same speed, but not multi > threaded scripts.Ruby''s thread scheduler interferes with epoll.. another reason why its better to avoid ruby threads and stick to the Reactor and Deferrable patterns.> Also with kqueue I believe there may be something wrong with the > implementation, as when using it for some reason about 4/5 connections > are immediately unbound when connected from one machine to itself. > Select works well though. > May be related to > http://rubyeventmachine.com/ticket/5 > > It''s not mission critical since my production app will be linux, not > mac os x, but thought I''d mention it.I''ve noticed this as well. Aman -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/eventmachine-talk/attachments/20080626/361c0e38/attachment.html>
On Thu, Jun 26, 2008 at 9:27 PM, Aman Gupta <themastermind1 at gmail.com> wrote:> Ruby''s thread scheduler interferes with epoll.. another reason why its > better to avoid ruby threads and stick to the Reactor and Deferrable > patterns. >Ruby''s scheduler interferes with any external I/O multiplexing syscall, however it''s possible to circumvent this by replacing rb_thread_select()''s role in I/O multiplexing and having it schedule threads directly. However, to my knowledge EventMachine does not yet do this, but calls rb_thread_select() and defers to Ruby''s select()-based I/O multiplexing. A possible optimization to EventMachine is to schedule Ruby threads directly with rb_thread_schedule(). Using epoll should result in a massive decrease in an application''s CPU utilization, particularly when large numbers of concurrent connections are involved. If not, something''s wrong with the usage of epoll... -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/eventmachine-talk/attachments/20080626/55675aa2/attachment-0001.html>
another question: It appears that in em.cpp, we have ... int o = getsockopt (sd, SOL_SOCKET, SO_ERROR, &error, &len); if ((o == 0) && (error == 0)) { however it appears from the docs on getsockopt that 0 means success. I''m not sure what ''error'' means. Is this a bug? -R
On 27 Jun 2008, at 04:56, Tony Arcieri wrote:> On Thu, Jun 26, 2008 at 9:27 PM, Aman Gupta > <themastermind1 at gmail.com> wrote: > Ruby''s thread scheduler interferes with epoll.. another reason why > its better to avoid ruby threads and stick to the Reactor and > Deferrable patterns. > > Ruby''s scheduler interferes with any external I/O multiplexing > syscall, however it''s possible to circumvent this by replacing > rb_thread_select()''s role in I/O multiplexing and having it schedule > threads directly. > > However, to my knowledge EventMachine does not yet do this, but > calls rb_thread_select() and defers to Ruby''s select()-based I/O > multiplexing. > > A possible optimization to EventMachine is to schedule Ruby threads > directly with rb_thread_schedule().I committed an experimental patch for this a while back, and will go back to researching it when I have cheaper branches. At the time I backed out the patch because we were seeing occasional crashes reported by Aman who was testing that branch at the time. I also was not able to record any significant speed difference between rb_thread_select() and rb_thread_schedule(), across different multiplexing widths and different numbers of threads.> Using epoll should result in a massive decrease in an application''s > CPU utilization, particularly when large numbers of concurrent > connections are involved. > > If not, something''s wrong with the usage of epoll... > > -- > Tony Arcieri > medioh.com _______________________________________________ > Eventmachine-talk mailing list > Eventmachine-talk at rubyforge.org > http://rubyforge.org/mailman/listinfo/eventmachine-talk-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/eventmachine-talk/attachments/20080627/06c4ee3f/attachment.html>
>> Also with kqueue I believe there may be something wrong with the >> implementation, as when using it for some reason about 4/5 connections >> are immediately unbound when connected from one machine to itself. >> Select works well though. >> May be related to >> http://rubyeventmachine.com/ticket/5 >> >> It''s not mission critical since my production app will be linux, not >> mac os x, but thought I''d mention it. > > I''ve noticed this as well. > AmanIn latest news, it appears that, on OS X, if you ever use all available file descriptors and are multi-threaded, it is possible that either the thread running EM or another thread will never be scheduled again, causing you to think "why isn''t EM running anymore??". This might well be a Ruby bug where it doesn''t handle certain edge cases in OS X with select. I think I may have run into something possibly related before. Fix for now: use linux. and a question: It appears we don''t handle the case of a socket read erring with "resource temporarily unavailable" -- if it does I assume we should keep the socket around? Here''s what the code currently does: int total_bytes_read = 0; char readbuffer [16 * 1024 + 1]; int unavailable = 0; for (int i=0; i < 10; i++) { int r = recv (sd, readbuffer, sizeof(readbuffer) - 1, 0); if (r > 0) { total_bytes_read += r; LastRead = gCurrentLoopTime; readbuffer [r] = 0; _DispatchInboundData (readbuffer, r); } else if (r == 0) { break; } else { // we might get here in the case of a socket that reads as ''currently unavailable'' -- the unhandled case. // we break out and close the socket since we never read anything, and assume that means a closed socket break; } } if (total_bytes_read == 0 && (unavailable == 0)) { ScheduleClose (false); } Thoughts? Thanks! -R
Regarding a socket read error, I believe you have to close it down on that exception. If you do not, you may be left with hanging descriptors and could run out of sockets even though none of them are valid anymore. I know this will happen in Windows but not 100% sure of other O/S''s. Roger Pack wrote:>>> Also with kqueue I believe there may be something wrong with the >>> implementation, as when using it for some reason about 4/5 connections >>> are immediately unbound when connected from one machine to itself. >>> Select works well though. >>> May be related to >>> http://rubyeventmachine.com/ticket/5 >>> >>> It''s not mission critical since my production app will be linux, not >>> mac os x, but thought I''d mention it. >>> >> I''ve noticed this as well. >> Aman >> > > > In latest news, it appears that, on OS X, if you ever use all > available file descriptors and are multi-threaded, it is possible that > either the thread running EM or another thread will never be scheduled > again, causing you to think "why isn''t EM running anymore??". This > might well be a Ruby bug where it doesn''t handle certain edge cases in > OS X with select. I think I may have run into something possibly > related before. Fix for now: use linux. > > > and a question: > It appears we don''t handle the case of a socket read erring with > "resource temporarily unavailable" -- if it does I assume we should > keep the socket around? > > Here''s what the code currently does: > > int total_bytes_read = 0; > char readbuffer [16 * 1024 + 1]; > int unavailable = 0; > for (int i=0; i < 10; i++) { > int r = recv (sd, readbuffer, sizeof(readbuffer) - 1, 0); > > if (r > 0) { > total_bytes_read += r; > LastRead = gCurrentLoopTime; > readbuffer [r] = 0; > _DispatchInboundData (readbuffer, r); > } > else if (r == 0) { > break; > } > else { > // we might get here in the case of a socket that reads as ''currently > unavailable'' -- the unhandled case. > // we break out and close the socket since we never read anything, and > assume that means a closed socket > break; > } > > } > > > if (total_bytes_read == 0 && (unavailable == 0)) { > ScheduleClose (false); > } > > > Thoughts? > Thanks! > -R > _______________________________________________ > Eventmachine-talk mailing list > Eventmachine-talk at rubyforge.org > http://rubyforge.org/mailman/listinfo/eventmachine-talk > >