Still working on Myrddin, I was perplexed by how much slower the engine appeared to be in console mode compared to being run inside a GUI.
After spending quite a bit of time with various MSVC compiler options, Task Manager, and Intel's VTUNE (which I highly recommend, by the way), I have discovered that it is the call to kbhit() that is taking an average of 30% of the CPU, as sometimes as much as 50%.
Task Manager shows the program CSRSS.EXE as hogging the CPU.
VTUNE shows kbhit() calling the Windows Kernel function GetNumberOfConsoleInputEvents(), which then calls the NTDLL function CsrClientCallServer() function. It is this last function that appears to be the culprit.
Here's all of the relevant code:
Code: Select all
/*========================================================================
** InitializeInput -- Open the stdin pipe for reading
**========================================================================
*/
void InitializeInput(void)
{
DWORD dw;
input_handle = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(input_handle, &dw);
setbuf(stdout, NULL);
}
/*========================================================================
** IsInputAvailable -- Check the stdin pipe for input
**========================================================================
*/
int IsInputAvailable(void)
{
DWORD nchars;
if (stdin->_cnt > 0)
return 1;
if (is_pipe)
{
if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL))
return 1;
return (nchars);
}
else
return(_kbhit());
}
/*========================================================================
** CheckForInput - Check for user input
**========================================================================
*/
BOOL CheckForInput(BOOL bWaitForInput)
{
if (bWaitForInput == FALSE)
{
if (!IsInputAvailable())
return(FALSE);
}
if (!fgets(line, 256, stdin))
return(-1); // shouldn't ever happen
if (line[0] == '\n')
return(FALSE);
#if LOGFILE
fprintf(logfile, "> Received %s", line);
#endif
sscanf(line, "%s", command);
return(TRUE);
}
I call CheckForInput() about once every 8K nodes. Changing how often I call it does not seem to have an appreciable effect (which is also very bizarre). Running Myrddin from inside the compiler (for both the release and the debug versions) is no different from running it manually from Windows.
I've compiled Crafty with the same settings, and Greko as well. Neither of the resulting programs show the same behavior as with Myrddin. As a last result, I have even copied the equivalent code from Crafty, with the same poor results.
Clearly, I'm missing something, which I hope that somebody out there has had to deal with before. Any recommendations would be most welcome. This is not how I expected to spend my time working on Alpha 2.
jm