Yes, I thought about this trick, but I stumbled at SMP. It is not so easy to extend to SMP because you would need to collect data at each split point and track it back....hgm wrote:You could even do it for free. If you have some array indexed by ply (like killers...), which is only used in full-width search, initialize it by something invalid, and after the search, check how far it was overwritten.
UCI: seldepth
Moderators: hgm, Rebel, chrisw
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: UCI: seldepth
-
- Posts: 481
- Joined: Thu Apr 16, 2009 12:00 pm
- Location: Slovakia, EU
Re: UCI: seldepth
One line of code I would not call "too costly to implement".
In scout_search() and pv_search() [but not in quiesce*()] I have this:
The code above compiles to one conditional jump, which is predicted correctly 99% according to intel's vtune. It makes sense because >60% of nodes are spent in q-search anyway.
when in MP mode, sending output involves collecting info from all threads:
In scout_search() and pv_search() [but not in quiesce*()] I have this:
Code: Select all
if (board.ply > thread->stats.maxply)
thread->stats.maxply = board.ply;
when in MP mode, sending output involves collecting info from all threads:
Code: Select all
int seldepth = 0;
for (i==0; i < num_threads; i++) {
if (threads[i].stats.maxply > seldpeth)
seldepth = threads[i].stats.maxply;
}
-
- Posts: 481
- Joined: Thu Apr 16, 2009 12:00 pm
- Location: Slovakia, EU
Re: UCI: seldepth
Ouch, I should not post any code after 9pmrvida wrote:Code: Select all
int seldepth = 0; for (i==0; i < num_threads; i++) { if (threads[i].stats.maxply > seldpeth) seldepth = threads[i].stats.maxply; }
Code: Select all
int seldepth = 0;
for (int i=0; i < num_threads; i++) {
if (threads[i].stats.maxply > seldpeth)
seldepth = threads[i].stats.maxply;
}
-
- Posts: 224
- Joined: Mon Mar 12, 2007 7:31 pm
- Location: Bonn, Germany
Re: UCI: seldepth
It should be noted however that using such approaches, you can send seldepth only when you send something anyway (and therefore check the array). You don't notice immediately when the array grows. With my approach, I can send seldepth immediately when it is reached. Of course there is not much value in that behaviour.hgm wrote:You could even do it for free. If you have some array indexed by ply (like killers...), which is only used in full-width search, initialize it by something invalid, and after the search, check how far it was overwritten.
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: UCI: seldepth
Yes this is the most natural and straightforward approach, I see you have direct access to Thread object by 'thread' pointer.rvida wrote:One line of code I would not call "too costly to implement".
In scout_search() and pv_search() [but not in quiesce*()] I have this:
Code: Select all
if (board.ply > thread->stats.maxply) thread->stats.maxply = board.ply;
Currently in SF access is by an array index threads[threadID], this implies a multiplication of threadID * sizeof(Thread) when compiler resolves the address....so actually you gave me two ideas instead of one
-
- Posts: 224
- Joined: Mon Mar 12, 2007 7:31 pm
- Location: Bonn, Germany
Re: UCI: seldepth
I think I located what "some reason" is.Onno Garms wrote:For some reason, it can happen that the PV is shorter than depth,
Stockfish does not track the PV. It just tries to retrieve the PV from the TT after a move is finished.
This will not always be successful. Not just because of possible early overwrites, also because moves that fail low never get written into the TT. Consequently SF might find a move in the TT that was best at shallower depth. The PV is read incorrectly then.
This can result in incorrect output of the PV. I'm not sure if this also results in an Elo loss (because the correct PV is not written back into the TT). To find an answer, an implementation where search() returns the partial PV would be needed.
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: UCI: seldepth
In case of a PV node the best move is always written to TT even if is not able to cut-off against beta.Onno Garms wrote: This will not always be successful. Not just because of possible early overwrites, also because moves that fail low never get written into the TT. Consequently SF might find a move in the TT that was best at shallower depth. The PV is read incorrectly then.
This can result in incorrect output of the PV. I'm not sure if this also results in an Elo loss (because the correct PV is not written back into the TT). To find an answer, an implementation where search() returns the partial PV would be needed.
It is true that if it fails low then it is not written, but in a "normal" search you return an exact score after having resolved all the fails high/low along the PV line.
BTW we have tested when we moved to this scheme from the triangular array one and result was no ELO change.
-
- Posts: 224
- Joined: Mon Mar 12, 2007 7:31 pm
- Location: Bonn, Germany
Re: UCI: seldepth
In deed. But in another threat we had a discussion about printing PVs that failed high or low.mcostalba wrote: It is true that if it fails low then it is not written, but in a "normal" search you return an exact score after having resolved all the fails high/low along the PV line.
Good to know. So the PV scheme is just a matter of an analysis friendly output.BTW we have tested when we moved to this scheme from the triangular array one and result was no ELO change.