Ed Gilbert wrote:I have a general question about what others are doing in qsearch. I tried to improve the qsearch in my English checkers program recently, but didn't get the results I expected. Because of the way I structured the search many years ago, it does not have a separate qsearch function. It's all done as portions of one search function, by taking different paths when depth <= 0. There is no hashtable probing or search reductions, but most other things still occur, such as repetition draw detection, egdb probing, and move sorting based on history and killers. So I thought, because it would be more efficient to move this into a separate qsearch function which could avoid multiple branches that now skip hashtable probing and storing, IID, LMR and other reductions, this should be faster. I also skipped history and killer table lookups and sorting of the movelist in this new qsearch function, so that is the primary functional difference between the original and new code. My results with the new qsearch function are that the search is about 25% faster in pure nodes/sec, but it tests a little worse in engine matches. Since the main difference is that my new qsearch no longer does movelist sorting, I'm guessing that is the reason. So I'm wondering if any of the other programmers have experience with sorting or not sorting the movelists in qsearch. I expect this also depends on what moves are searched in qsearch. If only captures are extended then probably the movelists are short and not worth sorting, but when non-side captures occur, those are just typical non-capture movelists.
To keep it fast I try to keep qsearch as simple as possible, I only sort at rank and try to move with the most advanced man first, this is accomplished by the move-generator. I don't probe the hash-table in quiescence, updating and probing the hash-table is very costly and slows down my program to a crawl, another problem is that the hash-table gets overloaded very quickly when you stuff 100 million nodes/sec. into it. The moves that I search in quiescence are captures, promotions and moves that trigger a non losing exchange and maybe I will add moves with the foremost man when it is free to move (like moves with an advanced passed pawn in chess). This scheme looks very much like what Fabien is doing, I did almost the same in my 1992 engine, it is a bit top heavy sometimes but it seems to work fine. Since most moves in quiescence are non reversible I check in the last version of my engine only at depth zero for repetitions and in this case there is no need to update the Zobrist hash in quiescence which gives it another small boost.
When I enable your EGDB (in quiescence) I only use non cached data in the PV and at non PV nodes I only use cached data, this helps to keep the slowdown in the order of a factor of 2.
Joost