Page 1 of 2

Using Sleep() while waiting for input

PostPosted: 22 Jan 2006, 22:46
by Naum
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

Re: Using Sleep() while waiting for input

PostPosted: 22 Jan 2006, 23:06
by Uri Blass
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

Re: Using Sleep() while waiting for input

PostPosted: 22 Jan 2006, 23:22
by Naum
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

Re: Using Sleep() while waiting for input

PostPosted: 22 Jan 2006, 23:59
by Uri Blass
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

Re: Using Sleep() while waiting for input

PostPosted: 23 Jan 2006, 00:09
by Uri Blass
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

Re: Using Sleep() while waiting for input

PostPosted: 23 Jan 2006, 02:14
by Naum
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

Re: Using Sleep() while waiting for input

PostPosted: 23 Jan 2006, 08:14
by Alessandro Scotti
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.

Re: Using Sleep() while waiting for input

PostPosted: 23 Jan 2006, 13:14
by Uri Blass
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

Re: Using Sleep() while waiting for input

PostPosted: 23 Jan 2006, 17:37
by Anthony Cozzie
Just out of curiosity, how do you get the IO thread to block and handle timing at the same time?

anthony

Re: Using Sleep() while waiting for input

PostPosted: 23 Jan 2006, 18:58
by Naum
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

Re: Using Sleep() while waiting for input

PostPosted: 19 Feb 2006, 22:18
by José Carlos
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?

Re: Using Sleep() while waiting for input

PostPosted: 19 Feb 2006, 22:56
by Alessandro Scotti
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:

Re: Using Sleep() while waiting for input

PostPosted: 20 Feb 2006, 13:36
by Daniel Shawul
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

Re: Using Sleep() while waiting for input

PostPosted: 20 Feb 2006, 13:42
by mathmoi
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.

Re: Using Sleep() while waiting for input

PostPosted: 20 Feb 2006, 14:01
by Alessandro Scotti
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.)

Re: Using Sleep() while waiting for input

PostPosted: 20 Feb 2006, 15:24
by mathmoi
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.

Re: Using Sleep() while waiting for input

PostPosted: 21 Feb 2006, 15:43
by Richard Pijl
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...

Re: I cannot poll stdin !

PostPosted: 21 Mar 2006, 22:28
by Chan Rasjid
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

Re: I cannot poll stdin !

PostPosted: 21 Mar 2006, 23:08
by Alessandro Scotti
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).

Re: I cannot poll stdin !

PostPosted: 21 Mar 2006, 23:15
by Sven Schüle
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.