• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 330
  • Last Modified:

CPU time for poll

When select is used with readfds and writefds, the exe occupies lot of CPU time.  When monitored using the prof, it says poll and select takes lot of time.   when writefds is removed,  It does not occupy CPU resouces.  Why is it so?  Am I forgetting something else inorder to have writedfds also to be polled in select?
0
ramalaks
Asked:
ramalaks
  • 3
  • 3
  • 2
1 Solution
 
basantCommented:
I don't think "select" takes that much time. However polling may be costly depend on the fequency.
Can u post some code or psuedo code what r u doing.
0
 
ramalaksAuthor Commented:
in main,


.....

while(1)
{

nready = select(maxfds+1, &readFds, &writeFds, NULL,&tm); /* tm val is 1 sec */

if (nready > ) {
      
      take actions....
}

} /*for while loop */


I do not have any poll in my code.  The prof gives select and _poll with 80% of the CPU time.
0
 
basantCommented:
Why did you set the time to 1 sec. You can have a large time interval here. The select system call will automatically return if one of the descriptor has got some signal.
0
[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

 
Anju111599Commented:
From looking at your code, I have a couple of observations/suggestions:

1.  Try using the FD* macros defined in one of the system header files (sys/time.h on HP-UX 10.20):  i.e. FD_SETSIZE, FD_ZERO, FD_SET, FD_ISSET.

2.  The timeout variable for HP-UX is specified in the man page as a "struct timeval".  The variable name you use, "tm", leads me to suspect you're using a struct tm.  Is this correct for your platform?  If not, it could be causing select to return too quickly.

Let me know if this makes any difference.

Anju
0
 
Anju111599Commented:
One more thing.  You should only map in writefds when you actually want to write something.  Otherwise, select will return immediately if any of the writefds is writeable, which will most likely be all the time.  Example:

int myReadFDs[2], myWriteFDs[2];
int nFDs = ((sizeof(myReadFDs)/sizeof(int));

.... // open fds

while (1)
{
  int nReady;
  fdset sRead, sWrite;
  struct timeval sTimeout;

  sTimeout.tv_sec = 5;  // 5 Sec
  sTimeout.tv_usec = 0; // 0 uSec

  FD_ZERO(&sRead);
  FD_ZERO(&sWrite);

  for (iFD=0; iFD<nFDs; iFD++)
    {
    // Always map read FDs
    FD_SET(myReadFDs[iFD], &sRead);

    // Map write FDs only if write pending
    if (WritePending(myWriteFDs[iFD]))
      FD_SET(myWriteFDs[iFD], &sWrite);
    }

    nReady = select( FD_SETSIZE, &sRead, &sWrite, NULL, &sTimeout);
    // Check for signal interruption
    if (nRead == -1)
      if (errno == EINTR)
        continue;  // restart select

  for (iFD=0; iFD<nFDs; iFD++)
    {
    if (FD_ISSET(myReadFDs[iFD], &sRead))
      HandleRead( myReadFDs[iFD] );
    if (FD_ISSET(myWriteFDs[iFD], &sWrite))
      HandleWrite( myWriteFDs[iFD] );
    }

  ... // Other processing
}

0
 
ramalaksAuthor Commented:
For basant,

I will try increasing the tm value to 5 sec and see what happens.

For Anju,


What I had given was sample/pseudo code. I am using FD_SET, CLR, ISSET macros for setting and clearing .etc

And also my "tm" is of type struct timeval which is a system defined struture.  

The code you have given looks like what I am tring to do.  You may be right in setting the write fd only when I have something to write.  I have not added that in my code.  

I will try making those changes and see what happens.  thanks for the comment to both of you.
0
 
ramalaksAuthor Commented:
It seems to be working if I set the writeFds only when I want to write.  Otherwise, the select will return immidiately with alway writeFds set which happens always and the loop goes on like this forever which takes more CPU time.  

Points to anju.
thanks.
0
 
Anju111599Commented:
Just a couple more short tips.  You may already know them, but perhaps not.  If not, they could possibly save you hours or even days of trouble...

After the problems youv'e just experienced, you might be led to think that a file descriptor is always writeable and be tempted to simply exclude it from the select mask all of the time.  Don't do that!  For example, if the fd is a socket, the send buffer could become full.  If this happens, a write could fail, or worse, it could block depending upon the socket options you've set.  Always map it into the select mask just prior to writing to it.

Another thing is that you can "peek" at the buffer of a fd which has a read pending and find out how many bytes are available for reading.  To do this, see the man page for ioctl, and in particular, the FIONREAD option:  

  int nBytes;
  ioctl( fd, FIONREAD, &nBytes );

Last, if you're communicating simple line-based text via sockets or serial ports, consider using line mode.  You can use ioctl to set options on the socket which will cause the kernel to only wake up select for a readable fd when there is a full line of text in the buffer.  This prevents you from having to read partial lines and paste them together all the time.  See the ioctl man pages (man -k ioctl) for details.

Good luck!
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now