UCI extension: nodestime
Posted: Sun Mar 22, 2015 7:00 pm
When running more games in parallel, or simply when running a game with a background process, due to how OS scheduling works, there is no
guarantee that the CPU resources allocated evenly between the two players.
This introduces noise in the result that leads to unreliable result and in the worst cases can even invalidate the result.
For instance in SF test framework we avoid running from clouds virtual machines because are a known source of very unstable CPU speed.
To overcome this I propose a simple extension to UCI protocol, aimed at being minimal invasive easy to implement both for engine authors and tournament managers.
The idea is to use searched nodes instead of time, and to convert time to/from nosed searched in as few places as possible.
So, starting from current protocol:
http://wbec-ridderkerk.nl/html/UCIProtocol.html
I propose to add to the 'go' command definition the following line:
* nodestime
tells the engine to use nodes searched instead of wall time to account for elapsed time.
When nodestime is sent, the following 'go' command parameters change their meaning in the following way:
* wtime
white has x msec left on the clock, or has x nodes left to search if nodestime is set
* btime
black has x msec left on the clock, or has x nodes left to search if nodestime is set
* winc
white increment per move in mseconds if x > 0, or in number of nodes if nodestime is set
* binc
black increment per move in mseconds if x > 0, or in number of nodes if nodestime is set
The nice thing is that the only change required to the engine is to account for elapsed time no more in millisecs since search is started, but in nodes searched since search is started. All the remaining logic, and in particular all the time management remains unchanged as long as is computed as relative to the values of wtime and btime, as is the case in all the engines I know of. If the engine, as is usual, sends 'nodes' value as part of its 'info' message, then nothing more is required.
The job of the tournament manager is as well very easy.
The user set the GUI to use 'nodestime', for instance setting a nodes_per_seconds configuration parameter. This is not part of UCI protocol and is reported here just as an example. So assume user sets:
nodes_per_seconds = 800.000
and all the other parameters as usual. When the GUI sends the 'go' command, it has just to add parameter 'nodestime' and convert wtime and friends from millisecs to nodes:
wtime *= nodes_per_seconds;
btime *= nodes_per_seconds;
winc *= nodes_per_seconds;
winc *= nodes_per_seconds;
Upon receiving 'bestmove', the gui uses the last 'nodes' info received from engine to convert back from nodes to time:
elapsed_time = nodes * 1000 / nodes_per_seconds; // In millisecs
Then uses elapsed_time as the time spent by the engine to search the move.
The nice thing is that nodes_per_seconds doesn't need to be accurate, a gross approximation is enough because it only alters the effective TC. For instance if TC is set at 1 minute per game, and nodes_per_seconds is set at 800.000, while the real engine speed is of 1600000 nodes per second, the only effect is that the game will last on average half time, like if TC was set at 30 seconds per game.
guarantee that the CPU resources allocated evenly between the two players.
This introduces noise in the result that leads to unreliable result and in the worst cases can even invalidate the result.
For instance in SF test framework we avoid running from clouds virtual machines because are a known source of very unstable CPU speed.
To overcome this I propose a simple extension to UCI protocol, aimed at being minimal invasive easy to implement both for engine authors and tournament managers.
The idea is to use searched nodes instead of time, and to convert time to/from nosed searched in as few places as possible.
So, starting from current protocol:
http://wbec-ridderkerk.nl/html/UCIProtocol.html
I propose to add to the 'go' command definition the following line:
* nodestime
tells the engine to use nodes searched instead of wall time to account for elapsed time.
When nodestime is sent, the following 'go' command parameters change their meaning in the following way:
* wtime
white has x msec left on the clock, or has x nodes left to search if nodestime is set
* btime
black has x msec left on the clock, or has x nodes left to search if nodestime is set
* winc
white increment per move in mseconds if x > 0, or in number of nodes if nodestime is set
* binc
black increment per move in mseconds if x > 0, or in number of nodes if nodestime is set
The nice thing is that the only change required to the engine is to account for elapsed time no more in millisecs since search is started, but in nodes searched since search is started. All the remaining logic, and in particular all the time management remains unchanged as long as is computed as relative to the values of wtime and btime, as is the case in all the engines I know of. If the engine, as is usual, sends 'nodes' value as part of its 'info' message, then nothing more is required.
The job of the tournament manager is as well very easy.
The user set the GUI to use 'nodestime', for instance setting a nodes_per_seconds configuration parameter. This is not part of UCI protocol and is reported here just as an example. So assume user sets:
nodes_per_seconds = 800.000
and all the other parameters as usual. When the GUI sends the 'go' command, it has just to add parameter 'nodestime' and convert wtime and friends from millisecs to nodes:
wtime *= nodes_per_seconds;
btime *= nodes_per_seconds;
winc *= nodes_per_seconds;
winc *= nodes_per_seconds;
Upon receiving 'bestmove', the gui uses the last 'nodes' info received from engine to convert back from nodes to time:
elapsed_time = nodes * 1000 / nodes_per_seconds; // In millisecs
Then uses elapsed_time as the time spent by the engine to search the move.
The nice thing is that nodes_per_seconds doesn't need to be accurate, a gross approximation is enough because it only alters the effective TC. For instance if TC is set at 1 minute per game, and nodes_per_seconds is set at 800.000, while the real engine speed is of 1600000 nodes per second, the only effect is that the game will last on average half time, like if TC was set at 30 seconds per game.