Using Sleep() while waiting for input

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

Do you use Sleep() for your input polling

Yes
5
20%
No
20
80%
 
Total votes : 25

Using Sleep() while waiting for input

Postby Naum » 22 Jan 2006, 22:46

While looking at Alessandro's very nicely written engine input library, I noticed that he uses something like:

while (!isInputAvailable())
Sleep(1);

I didn't like this solution and decided to test how much of opponents time you 'steal' if you use this technique instead of the Microsoft recommended WaitForSingleObject()

Result on my AMD3000 with WinXP was 0.1%
I am guessing that on a slower hardware and with the OS that doesn't have a proper implementation of multi-threading and process switching (Win98, etc.) the percentage might be bigger.

It is a small difference, but still it would be nice if people would avoid using Sleep() technique if possible.

Regards,
Alex
Naum
 
Posts: 87
Joined: 10 Oct 2004, 04:23
Location: Toronto

Re: Using Sleep() while waiting for input

Postby Uri Blass » 22 Jan 2006, 23:06

I do not use sleep but I also do not use threads.

When movei is calculating it checks every 8192 nodes for winboard commands so I do not need the alternative solution.

I was told that it is better to use threads but I do not like to replace a solution that works.

Uri
User avatar
Uri Blass
 
Posts: 727
Joined: 09 Oct 2004, 05:59
Location: Tel-Aviv

Re: Using Sleep() while waiting for input

Postby Naum » 22 Jan 2006, 23:22

Hi Uri,

I intended this to be just for fun. At least to me, this was an interesting information.

It doesn't matter what you do during the search. I am talking about input polling that engine is doing after it plays the move and starts waiting for Winboard to send the opponents move (ponder is off).

Regards,
Alex
Naum
 
Posts: 87
Joined: 10 Oct 2004, 04:23
Location: Toronto

Re: Using Sleep() while waiting for input

Postby Uri Blass » 22 Jan 2006, 23:59

Naum wrote:Hi Uri,

I intended this to be just for fun. At least to me, this was an interesting information.

It doesn't matter what you do during the search. I am talking about input polling that engine is doing after it plays the move and starts waiting for Winboard to send the opponents move (ponder is off).

Regards,
Alex


In ponder off after playing the move if I did not play because of winboard command I simply use fgets

Here is my code after making a move in case of ponder off when ponder is off

/*wait_flag tells us if we wait to new command*/
if (wait_flag==1)
{
if (!fgets(buffer, 256, stdin))
return;
}

Uri
User avatar
Uri Blass
 
Posts: 727
Joined: 09 Oct 2004, 05:59
Location: Tel-Aviv

Re: Using Sleep() while waiting for input

Postby Uri Blass » 23 Jan 2006, 00:09

Note that wait_flag=0 in case that I had to stop to search because of some winboard command that I still did not have time to implement(for example if I got the winboard command new or quit).

It was also the case for old movei for quit but was not the case for new and I decided to fix it after finding that movei lost game on time because fritz sent it the new command during the time that it was calculating and movei did not understand it.

?(move now) is winboard command that only ask me to stop the search and not do more things so in that case I do not change wait_flag from 1 to 0 but quit or new are commands that mean that I first stop the search and move and only later read it so in that case I need to change wait_flag to be 0 so movei will not wait passively to a new command.

The point is that I do not use sleep and I do not use the second thing that was mentioned here that is

Microsoft recommended WaitForSingleObject()

I use PeekNamedPipe that I learned from other programmers here but I do not know what is meant by WaitForSingleObject() and searching singleobj found no cases when that string is in my code.

Uri
User avatar
Uri Blass
 
Posts: 727
Joined: 09 Oct 2004, 05:59
Location: Tel-Aviv

Re: Using Sleep() while waiting for input

Postby Naum » 23 Jan 2006, 02:14

I am still not sure, but it seems that PeekNamedPipe can't be reliably used to check if there is something waiting in the input buffer used by fgets.
In order for your fgets() to work properly you are probably disabling the buffering (by calling setbuf and setvbuf).

I think that using the Win APIs only is safer then mixing the WinAPI and c runtime library functions.

You could replace the fgets() with something like:

WaitForSingleObject(hInput, INFINITE); // Waits until there is input available

ReadFile(hInput, buffer, length, &numRead);

hInput is the handle to stdin you use in your PeekNamedPipe call.
The only difference is that ReadFile works in the same way as _read() and not like fgets(), so you would have to do more coding to handle the new-line characters.
All this stuff is already implemented in Alessandro's free source.

Alex
Naum
 
Posts: 87
Joined: 10 Oct 2004, 04:23
Location: Toronto

Re: Using Sleep() while waiting for input

Postby Alessandro Scotti » 23 Jan 2006, 08:14

Naum wrote:While looking at Alessandro's very nicely written engine input library, I noticed that he uses something like:

while (!isInputAvailable())
Sleep(1);

I didn't like this solution and decided to test how much of opponents time you 'steal' if you use this technique instead of the Microsoft recommended WaitForSingleObject().


Hi Alex,
I have two comments on this:
1) the loop code is part of Kiwi, not of the System library;
2) it is not equivalent to WaitForSingleObject(), although it could be made equivalent to WaitForMultipleObjects() with some extra code.
User avatar
Alessandro Scotti
 
Posts: 306
Joined: 20 Nov 2004, 00:10
Location: Rome, Italy

Re: Using Sleep() while waiting for input

Postby Uri Blass » 23 Jan 2006, 13:14

Naum wrote:I am still not sure, but it seems that PeekNamedPipe can't be reliably used to check if there is something waiting in the input buffer used by fgets.
In order for your fgets() to work properly you are probably disabling the buffering (by calling setbuf and setvbuf).

I think that using the Win APIs only is safer then mixing the WinAPI and c runtime library functions.

You could replace the fgets() with something like:

WaitForSingleObject(hInput, INFINITE); // Waits until there is input available

ReadFile(hInput, buffer, length, &numRead);

hInput is the handle to stdin you use in your PeekNamedPipe call.
The only difference is that ReadFile works in the same way as _read() and not like fgets(), so you would have to do more coding to handle the new-line characters.
All this stuff is already implemented in Alessandro's free source.

Alex


I do not know if it cannot be safely used but I know that movei never lose on time in Leo's games

I do not have setbuf or setvbuf in movei.

In games under winboard there are rare cases that movei lose on time in the first move but it never lose on time in the middle of the game and in case of probability of even 0.01% not to get input from winboard I could expect it to lose on time in the middle of the game because of not getting the opponent move.

This may be thanks to the fact that I use some good code that dieter(programmer of yace suggested)

I remember some discussion from CCC when hyatt said also that it is not safe when later I understood that some code of dieter made it safe but this discussion is many months ago and I do not remember it now.

Here is the code that I use.

comments from dieter

static int is_pipe;
static HANDLE input_handle;

/* Call once at startup. thanks to Dieter for this function and the
same for input_available*/
void input_init(void)
{
DWORD dw;
input_handle = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(input_handle, &dw);
}


int input_available(void)
{
DWORD nchars;
/* When using Standard C input functions, also check if there
is anything in the buffer. After a call to such functions,
the input waiting in the pipe will be copied to the buffer,
and the call to PeekNamedPipe can indicate no input available.
Setting stdin to unbuffered was not enough, IIRC */
if (stdin->_cnt > 0)
{
return 1;
}
if (is_pipe)
{
/* When running under a GUI, you will end here. */
if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL))
return 1;
/* Something went wrong. Probably the parent program exited.
Could call exit() here. Returning 1 will make the next call
to the input function return EOF, where this should be
catched then. */
return nchars != 0;
}
else
if (nodes&Nodes_Frequency)
return 0;
else
return _kbhit(); /* In "text-mode" without GUI */
}

Uri
User avatar
Uri Blass
 
Posts: 727
Joined: 09 Oct 2004, 05:59
Location: Tel-Aviv

Re: Using Sleep() while waiting for input

Postby Anthony Cozzie » 23 Jan 2006, 17:37

Just out of curiosity, how do you get the IO thread to block and handle timing at the same time?

anthony
Anthony Cozzie
 
Posts: 50
Joined: 17 Oct 2004, 19:35

Re: Using Sleep() while waiting for input

Postby Naum » 23 Jan 2006, 18:58

What I have is getInput(Boolean wait) function.

If wait is false and there are no lines in my buffer, I call PeekNamedPipe and if there is nothing waiting just return.

If wait is true, only then I do blocking with WaitForSingleObject followed by the call to ReadFile.

From the search loop, every 64K nodes I call getInput(false). After I play the move and start waiting for the opponents response, I call getInput(true). If I replace the call to WaitForSingleObject with something like while (!isInputAvailable()) Sleep(1) everything works exactly the same, but this solution consumes 0.01% more CPU time.

I am sure Uri and others are doing something similar.

Alex
Naum
 
Posts: 87
Joined: 10 Oct 2004, 04:23
Location: Toronto

Re: Using Sleep() while waiting for input

Postby José Carlos » 19 Feb 2006, 22:18

Naum wrote:While looking at Alessandro's very nicely written engine input library, I noticed that he uses something like:

while (!isInputAvailable())
Sleep(1);

I didn't like this solution and decided to test how much of opponents time you 'steal' if you use this technique instead of the Microsoft recommended WaitForSingleObject()

Result on my AMD3000 with WinXP was 0.1%
I am guessing that on a slower hardware and with the OS that doesn't have a proper implementation of multi-threading and process switching (Win98, etc.) the percentage might be bigger.

It is a small difference, but still it would be nice if people would avoid using Sleep() technique if possible.

Regards,
Alex


I use scanf() to sit waiting for input. Is there any negative effect that I'm missing?
_____________________________
José Carlos Martínez Galán
User avatar
José Carlos
 
Posts: 102
Joined: 26 Sep 2004, 03:22
Location: Murcia (Spain)

Re: Using Sleep() while waiting for input

Postby Alessandro Scotti » 19 Feb 2006, 22:56

Jos? Carlos wrote:I use scanf() to sit waiting for input. Is there any negative effect that I'm missing?


Yes, you will be losing about 0.08 elo when matched against Kiwi with ponder off, so watch out! :wink:
User avatar
Alessandro Scotti
 
Posts: 306
Joined: 20 Nov 2004, 00:10
Location: Rome, Italy

Re: Using Sleep() while waiting for input

Postby Daniel Shawul » 20 Feb 2006, 13:36

I use Sleep(100) , I am not as "bad" as Alessandro :)
Seriously though, how are multi threaded engines supposed to
park the threads when it is not their turn? I am sure WaitForSingleObject() does something similar. Killing and creating does not seem a good solution.
Daniel
User avatar
Daniel Shawul
 
Posts: 366
Joined: 28 Sep 2004, 09:33
Location: Ethiopia

Re: Using Sleep() while waiting for input

Postby mathmoi » 20 Feb 2006, 13:42

Alessandro Scotti wrote:
Jos? Carlos wrote:I use scanf() to sit waiting for input. Is there any negative effect that I'm missing?


Yes, you will be losing about 0.08 elo when matched against Kiwi with ponder off, so watch out! :wink:


Hi Alessandro,

From what you say I understand that there is an overhead when using a blocking read instruction. Can you explain why?

I use something like that myself in a IO thread :

Code: Select all
do
{
 getline(cin, strInput);
 
 // do something with the input
} while (We don't need to leave);


it work pretty well and I don't think there is an overhead. The thread will be waked when input are avaible only, there is no need for a polling loop, so I would tough that this would be more efficient than the other presented methods. But I can be wrong.
mathmoi
 
Posts: 37
Joined: 30 Mar 2005, 21:23

Re: Using Sleep() while waiting for input

Postby Alessandro Scotti » 20 Feb 2006, 14:01

mathmoi wrote:From what you say I understand that there is an overhead when using a blocking read instruction. Can you explain why?


Hi Mathieu,
quite the contrary in fact! Blocking consumes no CPU, while polling takes a little amount of CPU time. So when playing against Kiwi, which polls when idle, you will be running at 99.9% or so of your speed and drop a fraction of Elo. (This assumes the above figure is correct, but IIRC when I tested it also taking into account the GUI overhead and several other system processes it was more like 99.99% or so.)
User avatar
Alessandro Scotti
 
Posts: 306
Joined: 20 Nov 2004, 00:10
Location: Rome, Italy

Re: Using Sleep() while waiting for input

Postby mathmoi » 20 Feb 2006, 15:24

Alessandro Scotti wrote:
mathmoi wrote:From what you say I understand that there is an overhead when using a blocking read instruction. Can you explain why?


Hi Mathieu,
quite the contrary in fact! Blocking consumes no CPU, while polling takes a little amount of CPU time.


Hi Alessandro,

Ok, it's what I tought. I just misunderstood your precedent post. Thanks.
mathmoi
 
Posts: 37
Joined: 30 Mar 2005, 21:23

Re: Using Sleep() while waiting for input

Postby Richard Pijl » 21 Feb 2006, 15:43

Daniel Shawul wrote:I use Sleep(100) , I am not as "bad" as Alessandro :)
Seriously though, how are multi threaded engines supposed to
park the threads when it is not their turn? I am sure WaitForSingleObject() does something similar. Killing and creating does not seem a good solution.
Daniel

I guess that when multiple search threads, chances are you won't be running a tournament on the same single CPU machine with multiple threads searching...
User avatar
Richard Pijl
 
Posts: 105
Joined: 26 Sep 2004, 21:09
Location: Minderhout, Belgium

Re: I cannot poll stdin !

Postby Chan Rasjid » 21 Mar 2006, 22:28

I am using Visual C++ 4 with Win98.

I now tries to poll stdin during search, but it hangs!

polling is :-

if (fgets(line, 256, stdin) > 0){
.....
}

Seems fgets does not return when stdin has nothing, but waits.
when I activate "move now", it works but hangs again unless activated with "move now" again.

What should I do ?

Thanks
Rasjid
Chan Rasjid
 
Posts: 73
Joined: 23 Feb 2005, 16:36
Location: Singapore

Re: I cannot poll stdin !

Postby Alessandro Scotti » 21 Mar 2006, 23:08

Hello Chad,
fgets blocks when there is no input, so you should call this function only when it's ok to block, or you are sure there is something to read (so it will not block).
Probably the best option is to take a look at open source engines like Crafty, Glaurung or Fruit and see what they do. You should find two basic functions there: one to read input (fgets or similar) and one to check whether there is input available (often called BiosKey... looks like a DOS name but hey that's what it's called).
User avatar
Alessandro Scotti
 
Posts: 306
Joined: 20 Nov 2004, 00:10
Location: Rome, Italy

Re: I cannot poll stdin !

Postby Sven Schüle » 21 Mar 2006, 23:15

Hi,

fgets() blocks until an input line could be read, so you can't use it for polling.

I propose to check the page of Alessandro Scotti, he has nice code for this stuff.

Sven

Edit: In the same minute I see that Alessandro himself proposes the opposite (to look at Crafty et al) but I really think that his own code is a good option because it seems to be written to work not only for one specific engine.
User avatar
Sven Schüle
 
Posts: 240
Joined: 26 Sep 2004, 20:19
Location: Berlin, Germany

Next

Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 13 guests