in reply to Socket IO with large (>1000) numbers of open sockets

How much cpu does your server use when it's polling those 1000 connections?

I ask, because think that you may be misinterpreting the results of your profiling.

What the profiling shows is that your program is spending 56% of elapsed wall-clock time in the can_read() call, but so what? You are not using a timeout value, which means that if there is nothing to do, no input to read, then that call waits until there is. What else would you have it do?

Unless you are thrashing your cpu, that is probably exactly where you want it to wait whilst there is nothing to do so that it is instantly read to roll as soon as there is.

If you are thrashing the cpu that is a different matter, but that is not reflected or demonstrated in the profiler output.

In that case, it may be that the implementation of IO::Select or the underlying calls on your system is such that whilst there is nothing avialable to read, it sits in a tight loop--like cartoon kids on a road trip:Are we there yet? Are we there yet? Are we there yet?--, and that is the cause of the thrashing.

In that case, it might be better to add a timeout to the can_read() call and explicitly sleep a little if there is nothing to do.

sub ckSockets { ... CHECK: my @breadys = $io_select_obj->can_read( 0.01 ); unless( @breadys ) { usleep( 0.1 ); ## See Time::HiRes ## Or select undef, undef, undef, 0.1; ## but that might be a "busy loop" also. goto CHECK; } ... }

But, unless you are experiencing high cpu loads when there is little or no traffic, then can_read() is exactly the right place for you program to spend most of it's time whilst it waits for something to do. Good on you for profiling, but be sure you are interpreting the results correctly.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: Socket IO with large (>1000) numbers of open sockets
by Ray Smith (Beadle) on Jun 11, 2007 at 16:50 UTC
    Thanks for the observations. I must appologize for the typo of "can_read()" introduced by my attempt to summarize the actual code. I really use can_read(0) because I do lots of work when there is no input to process. You did help me find a bug in my code though. The new profile times appear close. Unless I'm missing something here, I seams that the time is taken by checkintg to see if there are ready sockets and gathering those sockets.
    User+System Time = 1255.587 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 56.9 714.4 733.43 341511 0.0002 0.0002 IO::Select::can_read 4.47 56.09 87.694 364493 0.0000 0.0000 BuddyUser::log 3.96 49.68 1294.3 337516 0.0000 0.0004 BuddyUser::ckUser 3.13 39.35 772.78 341511 0.0000 0.0002 HttpNb::ios_can_read
      I seams that the time is taken by checkintg to see if there are ready sockets...

      There is no way to know from the information you are supplying. Ie. a profile; and either entirely non-representative code or no code at all; and no indication of how much cpu your application is typically using.

      You say that you are doing lots of "other stuff" when no input is available, but what if there is none of that 'other stuff' to do either?

      In that case, you'll check for input and find nothing and wait no time. You'll check for 'other stuff' and find nothing to do, so you'll go back and check for input again and find nothing, so you'll check for...

      It's a tight loop with most of the work (polling 1000 sockets) occuring inside can_read(). So that what profiling shows you.

      Again, unless you are using an abnormal amount of cpu when there is little or no socket traffic, the profiles you are posting are not necessarily indicative of a problem.

      If you are using a large amount of cpu when there is little or no socket traffic, then it would probably benefit your application to insert a small sleep somewhere.

      Eg. if( @ready = can_read( .01 ) ){. That would reduce the 'busy loop' effect when there is nothing to do, and so reduce your cpu usage, but it would probably increase the proportion of time spent in can_read().

      But really, without more information, it's just speculation.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.