H.G.Muller wrote:Normally engines take their timing decisions based on wall-clock time, as can be for instance obtained through a call like GetTimeOfDay() or (in Windows) GetTickCount(). The idea of
nps 0 is that you would replace that by a call to a function like clock(), which measures only the time that the engine is using the CPU, but stops ticking when the engine process is stalled because it is waiting to be swapped into memory, or waiting because another process on the same computer is using the CPU. In this mode the engine should report this time in the time field of its Thinking Output, and the GUI will use this time reported by the engine to decrement the engine's clock, rather than its own time measurement.
So in an engine that containes a routine GetTime() to read the clock, to implement the nps command in it, you would have to change that routine to:
- Code: Select all
int GetTime()
{
if(nodeRate < 0) return GetTickCount(); // msec
if(nodeRate == 0) return clock()*(1000./CLOCKS_PER_SEC);
return nodeCount*(1000./nps);
}
Of course an efficient implementation would avoid actual division, by precomputing a reciprocal. E.g. factor = (1000<<20)/nps; and then use (nodeCount*factor) >> 20.
Ok, from your post I now understand that
1) negative nodeRate is used to disable this feature to use the traditional Wall time. I think this should be spelled out in the protocol. As I read the protocol, it looks like negative numbers are undefined. In fact, my current implementation attempt has is as an unsigned int
I will change it.
2) nodeRate == 0 the engine measure its own CPU time, regardless of the node counts. Is this really needed? How is it going to be used? The problem is that clock() can give serious problems for SMP engines. It may be needed to divide by the number of CPUS used. With two threads used, clock() could be up to twice as big as wall time. However, this is not portable and I think the standards say nothing about it. I am not an expert on this specific issue, but I think it will be a pain in the butt to maintain this portable. This may vary from compiler to compiler besides variations from OS to OS. Another problem with clock() is that the resolution could be really coarse.
3) positive numbers is the heart of the feature, to use the actual nodes as "clock".
What is the default value for nodeRate when the engine starts? I assume it should be any negative number?
The protocol says that I should keep this value until the next "new". But...
What value should I set it when I receive the next "new"? Should I leave the previous value untouched or should I reset it to the default value? or is it undefined?
Miguel
PS: I do not think that a division is a big problem. This code is not executed in every single node.