It seems Intel is unable to properly workout templates with 'static'
storage specifier.
Workaround using an anonymous namespace instead.
No functional change.
Currently we exit the loop when
abs(bestValue) >= VALUE_KNOWN_WIN
but there is no logical reason for this. It seems more
natural to re-search again with full open window.
This has practically no impact in most cases, we have a
'no functional change' running 'bench' command.
The trick here is to check for legality only in the
(rare) cases we have pinned pieces or a king move
or an en-passant.
This trick is able to increase the speed of perft
of more then 20%!
No functional change.
Simply reshuffling the code inverting the condition in next_attacker()
yields a miraculous speed up of more than 3% under gcc!
On my laptop a bench run goes from 320Knps to 330Knps
No functional change.
This allows to reduce the scanning for new X-ray attacks
according to the capturing piece type.
It seems to be just a very small speed increase in MSVC 64
bit and gcc 32 bit, I guess cache issues value more than some
instruction less to execute (as usual).
No functional change.
It is very difficult and risky to assure
that a running thread doesn't access a global
variable. This is currently true, but could
change in the future and we don't want to rely
on code that works 'by accident'. The threads
are still running when ThreadPool destructor is
called (after main() returns) and this could
lead to crashes if a thread accesses a global
that has been already freed. The solution is to
use an exit() function and call it while we are
still in main(), ensuring global variables are
still alive at threads termination time.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When many threds concurrently print you need to serialize
the access to std::cout to avoid output lines are intermixed
with the contents of each thread.
This is not strictly needed at the moment because
only main thread prints out, although some ad-hoc
test could trigger UCI::loop() printing while searching.
Anyhow we want to lift this pretty avoidable constrain
also as a prerequisite for future work.
This patch just introduces the support, next one will enable
the serialization.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Before the search we setup the starting position doing all the
moves (sent by GUI) from start position to the position just
before to start searching.
To do this we use a set of StateInfo records used by each
do_move() call. These records shall be kept valid during all
the search because repetition draw detection uses them to back
track all the earlier positions keys. The problem is that, while
searching, the GUI could send another 'position' command, this
calls set_position() that clears the states! Of course a crash
follows shortly.
Before searching all the relevant parameters are copied in
start_searching() just for this reason: to fully detach data
accessed during the search from the UCI protocol handling.
So the natural solution would be to copy also the setup states.
Unfortunatly this approach does not work because StateInfo
contains a pointer to the previous record, so naively copying and
then freeing the original memory leads to a crash.
That's why we use two std::auto_ptr (one belonging to UCI and another
to Search) to safely transfer ownership of the StateInfo records to
the search, after we have setup the root position.
As a nice side-effect all the possible memory leaks are magically
sorted out for us by std::auto_ptr semantic.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Should be more clear from where the 'magic' numbers
come from.
Also bit of reformat while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of just size(). Although code is longer,
should be more immediate to understand when reading.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
To mimics C++11 std::mutex and std::condition_variable,
also rename locks and condition variables to be more
uniform across the classes.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Reduce of one instruction. It seems a tad faster on
the profiler now. Very slightly but anyhow it is a
code semplification.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This better mimics std::vector::operator[] and
fixes a warning with MSVC 64bit.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Further reduce redundancy in move generation.
Veirifed no speed regression on MSVC, Clang and gcc.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Greatly simplify these very performace critical functions.
Amazingly we don't have any speed regression actually under
MSVC we have the same assembly for generate_moves() !
In generate_direct_checks() 'target' is calculated only
once being a loop invariant.
On Clang there is even a slight speed up.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Are used by Position but do not belong to that class,
there is only one instance of them (that's why were
defined as static), so move to a proper namespace instead.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Check we are the last slave of the split point
before to wake up the master. This should avoid
spurious wakes up.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We can detect the split point master also from within idle_loop,
so we can call the function without parameters and remove an
overloaded member hack in Thread class.
Note that we don't need to take a lock around curSplitPoint
when entering idle_loop() because if we are the master then
curSplitPoint cannot change under our feet (because is_searching
is set and so we cannot be reallocated), if we are a slave
we enter idle_loop() only upon Thread creation and in that case
is always splitPointsCnt == 0. This is true even in the very rare
case that curSplitPoint != NULL, if we have been already allocated
even before entering idle_loop().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Directly use the underlying std::map instead and avoid
a useless inheritance.
As a nice side-effect Options global object has now a
default c'tor avoiding possible issues with globals
initializations.
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Templetize MovePicker::next_move() member function instead. It
is easier and we also avoid the forwarding of MovePicker() c'tor
arguments in the common case.
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
First change: If Haiku is host platform, change
installation prefix to /boot/common/bin
Second change: Only link in pthreads if Haiku isn't
host platform.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And group there all the formatting functions but
uci_pv() that requires access to search.cpp variables.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use the helpers to format the PV info but without
writing to output stream (file or cout). Message
formatting and sending are two logically different
task.
Incidentaly reintroduce the pretty_pv() name,
from Glaurung memories :-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Simplifies the code and seems more natural.
We have a very small fucntional change becuase now
at PV nodes castles are extended one ply anyhow.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With warning level 4 MSVC complains that a default
assignment operator could not be generated due to
member 'file' is a reference (warning C4512).
Use a pointer instead of a reference and move
struct Tie outisde class Logger while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems more accurate: lsb is clear while 'first
bit' depends from where you look at the bitboard.
And fix compile in case of 64 bits platforms that
do not use BSFQ intrinsics.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of -O4 option that does not work with both mingw and
Linux gcc (tested with Clang 3.1).
As reported by Reed Kotler:
Turns out that -O4 is not a valid option for clang unless you have
the proper gold linker and plugins built. That's because -O4 enables
LTO, which writes out bitcode files during the compile, and then loads
those and optimizes them during the link phase.
It requires a linker that supports LLVM's LTO. There is a plugin for
Gold available as part of LLVM.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We have a signed integer here so let the return type
take in account that.
Found by Clang with -Weverything option.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Return a reference instead of void so to enable
chained assignments like
"p = q = Position(...);"
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Although a (little) functional change, we have no ELO change
but formula it is now more clear.
After 13019 games at 30"+0.05
Mod vs Orig 2075 - 2088 - 8856 ELO 0 (+- 3.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems the standard behaviour as implemented
in most engines although UCI protocol does not
specify what to do upon "ucinewgame" command.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Calculate the attacks only for the piece to disambiguate,
not for all.
Also some reformatting while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
At endgame time push the king near his pawns (actually
one of them).
Original idea is from Critter (although slightly different),
implementation is mine and is completely different from the
original, in particular it is different the algorithm to
compute the minimum distance from pawns.
After 19895 games at 15"+0.05
Mod vs Orig 3638 - 3248 - 13009 ELO +7
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Error is due to ambiguous overloading of operator^
because we have both the built-in operator^(int, int)
and the user defined operator^(Bitboard, Square).
This error does not trigger when using Makefile becuase,
due to luck, the user defined operator^(Bitboard, Square)
happens to be always defined _after_ opposite_colors() so
that compiler does not claim. But in case of Microsoft MSVC
we don't have a Makefile and the order of files compilation
is chosen by the compiler (in an unpredictable way). So it
could still happen that error is not detected (as in my case),
but in another case the order of compilation of the files could
be so that at some point both operator^ were defined before
opposite_colors() and this triggers the error.
The fix is much simpler than the explanation :-)
Reported by Quocvuong82.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently when we fail to open a book file, for instance
if it doesn't exsist, we leave Book::open() with ifstream
failbit set. If then the book file is added, we correctly
open it at next attempt, but failbit is still set so that
after opening we exit because ifstream::good() returns false.
The fix is to reset failbit upon exiting.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In case a book entry has 'count' field set to 0
we crash. Spotted by Clang's static analyzer.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So to be fully in sync with StateInfo, and move struct
to position.h, just below StateInfo.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Revision 2aac860db3 of 27 / 4 / 2012
changed can_castle() signatures from bool to int and
this broke the code that calculates polyglot hash key
in book.cpp
Instead of directly fixing the code we prefer to change
castling rights definitions to align to the polyglot ones
(as we did in previous patch). After this step we can simply
take internal castle rights as they are and use them
directly to calculate polyglot book hash key, as we do
in this patch that fixes the regression.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
To be aligned with PolyGlot book castle right definitions.
This will be used by next patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Early classify as known draws the positions
where white king is trapped on the rook file.
Suggested by Dan Honeycutt.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After extensive testing (I was off line this week and let
the test go on) it seems this change is useless:
After 33968 games on a QUAD (4 threads) at 15"+0.05
Mod vs Orig 5425 - 5550 - 22993 ELO -1 (+-2.1)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Only in case of promotion we care about an upper case
promotion piece char, so std::transform() is overkill
for the task.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Assumption: Junior sends promotions according to the side to move (ucase/lcase).
Fact: Stockfish generally handles promotion lcase.
Patch: Handling position fen input moves always with lcase promotions.
Ported back by Portfish. No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems ADL lookup is broken with the STLPort library. Peter says:
The compiler is gcc 4.4.3, but I don't know how many patches they
have applied to it. I think gcc has had support for Koenig lookup
a long time. I think the problem is the type of the vector iterator.
For example, line 272 in search.cpp:
if (bookMove && count(RootMoves.begin(), RootMoves.end(), bookMove))
gives the error:
jni/stockfish/search.cpp:272: error: 'count' was not declared in this scope
Here RootMoves is:
std::vector<RootMove> RootMoves;
If std::vector<T>::iterator is implemented as T*, then Koenig lookup
would fail because RootMove* is not in namespace std.
I compile with the stlport implementation of STL, which in its vector
class has:
typedef value_type* iterator;
I'm not sure if this is allowed by the C++ standard. I did not find
anything that says the iterator type must belong to namespace std.
The consensus in this thread
http://compgroups.net/comp.lang.c++.moderated/argument-dependent-lookup/433395
is that the stlport iterator type is allowed.
Report and patch by Peter Osterlund.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Let first argument to be the 'color'. This allows to align
pos.pieces() signatures with piece_list(), piece_count() and
all the other functions where 'color' argument is passed as
first one.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Hex representation doesn't add any value in those cases.
Preserve hex representation where more self-documenting
for instance for binary masks values.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems to increase SMP performances. To note that
this patch goes in the opposite direction of "Active
reparenting" where we try to reparent an idle slave
as soon as possible. Instead here we prefer to keep
it idle instead of splitting on a shallow / near the
leaves node.
After 11550 games on a QUAD (4 threads) at 15"+0.05
Mod vs Orig 1972 - 1752 - 7826 ELO +6 (+-3.6)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Set optimization level to 4 and get a 2.564% faster binary:
Stockfish (Clang, Level 4) bench:
$ make build ARCH=osx-x86-64 COMP=clang
(Clang does not support PGO)
Average of 4 trials:
Total time (ms): 5137.5
Nodes searched: 5631135
Nodes/second: 1096084.5
Stockfish (Clang, Level 3) bench:
$ make build ARCH=osx-x86-64 COMP=clang
(Clang does not support PGO)
Average of 4 trials:
Total time (ms): 5269.25
Nodes searched: 5631135
Nodes/second: 1068679.25
Stockfish (GCC, PGO) bench:
$ make profile-build ARCH=osx-x86-64
Average of 4 trials:
Total time (ms): 5286
Nodes searched: 5631135
Nodes/second: 1065292.25
Suggestion and performance tests by Daylen Yang.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A PvNode that givesCheck has been already granted
an extension of ONE_PLY in previous condition.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Makefile modified to support the clang compiler under Mac.
This was tested using clang 4 under Mountain Lion, but should
also work fine under Lion and possibly under Snow Leopard.
It requires the 'Xcode 4.x Command Line Tools' to be installed.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Since revision 374c9e6b63
we use also castling information to calculate king safety.
So before to reuse the cached king safety score we have to
veify not only king position, but also castling rights are
the same of the pre-calculated ones.
This is a very subtle bug, found only becuase even after
previous patch, consecutives runs of 'bench' _still_ showed
different numbers. Pawn tables are not cleared between 'bench'
runs and in the second run a king safety score, previously
evaluated under some castling rights, was reused by another
position with different castling rights instead of being
recalculated from scratch.
Bug spotted and tracked down by Balint Pfliegel
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we can call bench multiple times
from command prompt we need to ensure searched
nodes remain constant across different runs.
Spotted by Blint Pfliegel.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After 6K games at 60" + 0.1 on QUAD with 4 threads
this implementation fails to show a measurable increase,
result is well within error bar.
Perhaps with 8 or more threads resut is better but we
don't have the hardware to test. So retire for now and
in case re-add in the future if it proves good on big
machines.
The only good news is that we don't have a regression and
implementation is stable and bug-free, so could be reused
somewhere in the future.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The check for detecting when a split point has all the
slaves still running is done with:
slavesMask == allSlavesMask
When a thread reparents, slavesMask is increased, then, if
the same thread finishes, because there are no more moves,
slavesMask returns to original value and the above condition
returns to be true. So that the just finished thread immediately
reparents again with the same split point, then starts and
then immediately exits in a tight loop that ends only when a
second slave finishes, so that slavesMask decrements and the
condition becomes false. This gives a spurious and anomaly
high number of faked reparents.
With this patch, that rewrites the logic to avoid this pitfall,
the reparenting success rate drops to a more realistical 5-10%
for 4 threads case.
As a side effect note that now there is no more the limit of
maxThreadsPerSplitPoint when reparenting.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Check for a cutoff occurred also high in
the tree and not only at current split
point.
This avoids some more wasted reparenting.
No functional chnage.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is more correct given what the function does. In
particular single_bit() returns true also in case of
empty bitboards.
Of course also the usual renaming while there :-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of reparenting to oldest split point, try to reparent
to latest. The nice thing here is that we can use the YBWC
helpful master condition to allow the reparenting of a split
point master as long as is reparented to one of its slaves.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And update master->splitPointsCnt under lock
protection. Not stricly necessary because
single_bit() condition takes care of false
positives anyhow, but it is a bit tricky and
moving under lock is the most natural thing
to do to avoid races with "reparenting".
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In Young Brothers Wait Concept (YBWC) available slaves are
booked by the split point master, then start to search below
the assigned split point and, once finished, return in idle
state waiting to be booked by another master.
This patch introduces "Active Reparenting" so that when a
slave finishes its job on the assigned split point, instead
of passively waiting to be booked, searches a suitable active
split point and reprents itselfs to that split point. Then
immediately starts to search below the split point in exactly
the same way of the others split point's slaves. This reduces
to zero the time waiting in idle loop and should increase
scalability especially whit many (8 or more) cores.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Apart from the semplification it is now more clear that
the actual Tempo added was half of the indicated score.
This is becuase at start compute_psq_score() added half
Tempo unit and in do_move() white/black were respectively
adding/subtracting one Tempo unit.
Now we have directly halved Tempo constant and everything
is more clear.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is still enabled during fixed limit search so to
use it during fixed depth/nodes/time matches.
Bug reported by Daylen.
No functional changes.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Shrinking from [16] to [2][2] is able to speedup
perft of start position of almost 5% !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Shrink dimensions of the biggest stack consumers arrays.
In particular movesSearched[] can be safely shrinked
without any impact on strenght or risk of crashing.
Also MAX_PLY can be reverted to 100 with almost no impact
so to limit search recursion and hence stack allocation.
A different case is for MAX_MOVES (used by Movepicker's
moves[]), because we know that do exsist some artificial
position with about 220 legal moves, so in those cases SF
will crash. Anyhow these cases are never found in games.
An open risk remains perft, especially run above handcrafted
positions.
This patch originates from a report by Daylen that found
SF crashing on his Mac OS X 10.7.3 while in deep analysys
on the following position:
8/3Q1pk1/5p2/4r3/5K2/8/8/8 w - - 0 1
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now a fen file with Chess960 positions is
correctly parsed. But it is mandatory to set
"UCI_Chess960" option _before_ to call bench.
Note that this was not needed/possible before
adding the possibility to call 'bench' from
command prompt.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we can call bench on current position
we can directly use it to perform our perft.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we can call bench from command prompt
has a sense to teach bench to run the current
set position. To do this is enough to call bench
with 'current' as fen source parameter.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After extensive test Gary says:
"So, after 16k games at 10"+1" on an i7, the undefended rook test
looks to be not good (albeit by a very small margin).
3063 - 3093 - 9844 (-1).
I doubt that is causing the regression, but even so, it looks like
it's not worth keeping, and we can go back to the simpler undefended
minors check."
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Unfortunatly accessing thread local variable
is much slower than object data (see previous
patch log msg), so we have to revert to old code
to avoid speed regression.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Much faster then pthread_getspecific() but still a
speed regression against the original code.
Following are the nps on a bench:
Position
454165
454838
455433
tls
441046
442767
442767
ms (Win)
450521
447510
451105
ms (pthread)
422115
422115
424276
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After we release the SplitPoint lock the master, suppose
is main thread, can safely return and if a "quit" command
is pending, main thread exits and associated Thread object
is freed. So when we access master->is_searching a crash
occurs.
I have never found such a race that is of course very rare
becuase assumes that from lock releasing we go to sleep for
a time long enough for the main thread to end the search and
return. But you can never know, and anyhow a race is a race.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So to avoid a crash when setting the moves in
UCI "position startpos moves ...." command.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
But use the newly introduced local storage
for this. A good code semplification and also
the correct way to go.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use thread local storage to store a pointer to the thread we
are running on. This will allow to remove thread info from
Position class.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With this change sources are fully endianess
independent, so we can simplify the Makefile.
Somewhat surprisingly we don't have any speed
regression !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Erroneusly adds default positions to the fens
loaded from external file.
Bug introduced in adb71b8096
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The 2 overload functions map() accept a pointer to
EndgameBase<Value> or a pointer to EndgameBase<ScaleFactor>.
Because Endgame<E> is derived from one of them we can
directly use a pointer to this class to resolve the
overload as is needed in Endgames::add().
Also made class Endgames fully parametrized and no more
hardcoded to the types (Value or ScaleFactor) of endgames
stored.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A std::set (that is a rb_tree) seems really
overkill to store at most a handful of moves
and nothing in the common case.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is possible to start with 'stockfish', then from
command prompt type 'bench' and SF will do what you expect.
Old behaviour is anyhow preserved. As a bonus we can now
start from command line any UCI command understood by
Stockfish. The difference is that after execution of a
command from arguments SF quits, while at the end of the
same command from prompt SF stays in UCI loop.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Allows some code semplification and avoids directly
allocation and managing heap memory.
Also the usual renaming while there.
No functional change and no speed regression.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In particualr before to wake up main thread that
could take some random time. Until we don't reset
search time we are not able to correctly track
the elapsed search time and this can be dangerous
under extreme time pressure.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We need to wake up main thread if it is sleeping
waiting for stop or ponderhit, so we cannot skip
calling wait_for_search_finished().
Found by Othello1984.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In this case SF stop searching and goes sleeping
waiting for a stop / ponderhit before to return
best move. So when a "stop" arrives we need to wake
up the main thread again.
Another regression introduced by 3aa471f2a9,
hopefully the last one.
Thanks to Otello1984 to reporting this.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Renamed stuff and added comments. The aim is to make more
readable, at least by me ;-) , this newly added part of code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Incredible typo from my side!
The 2 tables are completely different, one counts 1s the
other returns the msb position. Even more incredible
the 'stockfish bench' command returns the same number
of nodes!!!
Spotted by Justin Blanchard.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add more detailed pawn shelter/storm evaluation
After 10670 games at 10"+0.05
Mod vs Orig 2277 - 1941 - 6452 ELO +11 !!!
The first real increase since 2.2.2, congratulations Gary !!!
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fixes a not so rare crash (once every 100 games)
newly introduced. Unfortunatly I am still not
able to figure out why :-(
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
There is no need to "invent" different names
from the original UCI parameters.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Penalty for undefended rook
Almost no change at longer TC, but perhaps there
is a tiny increase....
After 17522 games at 10"+0.05
Mod vs Orig 3064 - 2967 - 11491 ELO +2
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When quitting we should avoid RootPosition to be
destroyed while threads are still running, leading
to a crash. In case of a "stop" or "ponderhit"
command there is no need for the UI thread to wait.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And add final touches to this long patch series.
All the series has been verified against regression with
20K games at fast TC.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We have a clash with start_fn defined both as a
Thread memeber and as a function pointer type in
pthread_create().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We cannot set do_sleep flag of main thread before
"bestmove" is sent to GUI, otherwise GUI could send
immediately the next "go" command that triggers
start_thinking() and because do_sleep is set UI
thread resets the flag to launch a new search. But
when shortly after main thread returns to main_loop()
flag is incorrectly reset and main thread goes to sleep
hanging the engine.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We store pointers instead of Thread objects because
Thread is not copy-constructible nor copy-assignable
and default ones are not suitable. So we cannot store
directly in a std::vector.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Associate platform OS thread to the Thread class instead of
creating it from ThreadsManager.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Split the data allocation, now done (mostly once)
in read_uci_options(), from the wake up and sleeping
of the slave threads upon entering/exiting the search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems is the cause of strange and rare hangs
reported by some users where Stockfish stops
responding to GUI. It is not clear why but for
the moment revert the patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Not correct warning about use of an uninitialized
variable. The warning is not correct becuase we can
never reach the warned code when in SpNode, anyhow
the fix is simple.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A somewhat tricky function pointer cast allows us
to move the platform specifics to lock.h, the cast
is tricky because return type is not the same of the
casted function in Linux (for Windows return type is
a DWORD that is a long) but this should not be a
problem as long as the size is the same;
From: http://stackoverflow.com/questions/188839/function-pointer-cast-to-different-signature
"OpenSSL was only casting functions pointers to
other function types taking and returning the same
number of values of the same exact sizes, and this
(assuming you're not dealing with floating-point)
happens to be safe across all the platforms and
calling conventions I know of. However, anything
else is potentially unsafe."
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This should avoid some aliasing issues
with TT table access.
After 3913 games at 10"+0.05
Mod vs Orig 662 - 651 - 2600 ELO +0 (+- 6.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Even if not under attack. This seems to be good
especially on openings.
After 12112 games at 10"+0.05
Mod vs Orig 2175 - 1997 - 7940 ELO +5 (+- 3.7)
[Patch series from Gary, little edited by me]
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We need splitted Tie classes because MSVC stream library
takes a lock on buffer both on reading and on writing and
this causes an hang because, while searching, the I/O
thread is locked on getline() and when main thread is
trying to std::cout() something it blocks on the same
lock waiting for I/O thread getting some input and
releasing the lock.
The solution is to use separated streambuf objects for
cin and cout.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A big code simplification and cruft removing, make
Logger class a singleton and fully self conteined.
Also add direction indicators (">>" and "<<") to
better differentiate input and output lines in the
log file.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Using "o" as a parameter with the on_xxx(const UICOption& o)
functions is a bit dangerous because of confusion with "0".
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Some trial was needed to find the correct recipe but now
we log both stdin and stdout to file "io_log.txt".
Link http://spec.winprog.org/streams/ was very useful
to understand the details of iostreams implementation.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
By means of "Use Debug Log" UCI option it is possible to toggle
the logging of std::cout to file "out.txt" while preserving
the usual output to stdout. There is zero overhead when logging
is disabled and we achieved this without changing a single line
of exsisting code, in particular we still use std::cout as usual.
The idea and part of the code comes from this article:
http://groups.google.com/group/comp.lang.c++/msg/1d941c0f26ea0d81
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In particular before initialization. So that SF
seems more snappy at startup.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
As it was in Glaurung times. Also rearranged order
so that byTypeBB[0] is accessed before byTypeBB[x]
to be more cache friendly. It seems there is even
a small speedup.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also some microoptimizations, were there from ages
but hidden: the renaming suddendly made them visible!
This is a good example of how better naming lets you write
better code. Naming is really a kind of black art!
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Stick to UCI protocol that says:
* by default all the opening book handling is done by the GUI,
but there is an option for the engine to use its own book
("OwnBook" option, see below)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
UCI protocol it is not clear about what the engine
should be supposed to do when "ucinewgame" is
received. Stockfish simply sets the position to
start FEN, but it is redundant becuase the GUI always
resends the position after "ucinewgame" command, so
it seems we can safely ignore that command.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When a button fires UCIOption::operator=() is called and from
there the on_change() function. Now it happens that in case of
a button the on_change() function resets option's value to
"false" triggering again UCIOption::operator=() that calls again
on_change() and so on in an endless loop that is experienced
by the user as an application hang.
Rework the button logic to fix the issue and also be more clear
about how button works.
Reported by several people working with Scid and tracked down
to the "Clear Hash" UCI button by Steven Atkinson.
Bug recently introduced by 2ef5b4066e.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now we are forced to just use C++ iostream becuase
buffers are independent and using C library functions
like printf() or scanf() could yield to issues.
Speed up of about 1%.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Result of t.time * 1000 should be a 64 bit value, not an int.
Bug reported by several users.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fine tune newly introduced pinner bonus score:
After 34696 games at 2"+0.05
Mod vs Orig 7474 - 7087 - 20135 ELO +3 (+- 2.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So to be done only once at startup and in the (unlikely)
cases that a relevant UCI parameter is changed, instead
of doing it at the beginning of each search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Introduce 'on change' actions that are triggered as soon as
an UCI option is changed by the GUI. This allows to set hash
size before to start the game, helpful especially on very fast
TC and big TT size.
As a side effect remove the 'button' type option, that now
is managed as a 'check' type.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Self-documenting code instead of a tricky
bitwise tweak, not known by everybody.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add a bonus if a slider is pinning an enemy piece.
Idea from Critter.
After 27443 games at 2"+0.05
Mod vs Orig 5900 - 5518 - 16025 ELO +4 (+- 2.7)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Introduce and use a new Time class designed after
QTime, from Qt framework. Should be a more clear and
self documented code.
As an added benefit we now use 64 bits internally to get
millisecs from system time. This avoids to wrap around
to 0 every 2^32 milliseconds, which is 49.71 days.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Visual Studio 11 is worried that shift result could
overflow an integer, this is impossible becuase max
value of the shift is 4, but compiler cannot know it.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Pre compute castle path so to quickly test
for impeded rule.
This speeds up perft on starting position
of more than 2%.
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix this warning with MSVC 64 bits:
warning C4244: '=' : conversion from 'std::streampos' to 'size_t',
possible loss of data
Point is that std::streampos could be negative, while size_t
is always non-negative.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And introduce SPlitPoint bestMove to pass back the
best move after a split point.
This allow to define as const the search stack passed
to split.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is a prerequisite for next patch and simplifies
the function. testing at ultra fast TC shows no
regression.
After 24302 games at 2"+0.05
Mod vs Orig 5122 - 5038 - 13872 ELO +1 (+- 2.9)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Reverse the meaning of castleRightsMask[sq] so that now
is stored the castling right that will be removed in
case a move starts from or arrives to sq square. This
allows to simplify the code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of by square. This is a more conventional
approach, as reported also in:
http://chessprogramming.wikispaces.com/Zobrist+Hashing
We shrink zobEp[] from 64 to 8 keys at the cost of an extra
'and 7' at runtime to get the file out of the ep square.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We shouldn't need lock protection to increment
splitPointsCnt and set curSplitPoint of masterThread.
Anyhow because this code is very tricky and prone to
races bound the change in a single patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When updating castleRights in do_move() perform only one
64bit xor with zobCastle[] instead of two.
The trick here is to define zobCastle[] keys of composite
castling rights as a xor combination of the keys of the
single castling rights, instead of 16 independent keys.
Idea from Critter although implementation is different.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Because TT table is shared tte->move() could change
under our feet, in particular we could validate
tte->move() then the move is changed by another
thread and we call pos.do_move() with a move different
from the original validated one !
This leads to a very rare but reproducible crash once
every about 20K games.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
There is no need to limit the maximum ply searched to
100, with deep exclusion search extensions we could
reach it even with much smaller search depths.
The only drawback is an increase in stack usage, but
is limited mainly to id_loop(), in particular the
recursive search() functions are not affected.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Replace a 64 bit 'and' by two 32 bits ones and
use unsigned instead of int.
This simple patch increases perft speed of 6% on
my Intel Core 2 Duo !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
But only when needed, after a split point. This behaviour
does not apply when useSleepingThreads is false, becuase
in this case threads are not woken up at split points so
must be already running.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Rule says should be reset only after a capture and/or
a pawn move.
This incredible bug was here since Glaurung times !
Spotted by Kiriakos.
No functional change in the test bench because we
don't reach the 50 moves limits.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With default value of 100 no change in regard of current
behaviour. Increasing the value makes SF to think a
longer time for each move. Decreasing the value makes SF
to move faster.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This method belongs to Thread, not to ThreadsManager.
Reshuffle stuff in thread.cpp while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Release split point lock before to wake up
master thread. This seems to increase speed
in case "sleeping threads" are used:
After 7792 games with 4 threads at very fast TC (2"+0.05)
Mod vs Orig 1722 - 1627 - 4443 ELO +4 (+- 5.1)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When allocating a slave we set both is_searching
and splitPoint under lock protection.
Unfortunatly the order in which the variables are
set is not defined. This article was very clarifying:
http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/
So when in idle loop we test for is_searching and then
access splitPoint, it could happen that splitPoint is still
not updated leading to a possible crash.
Fix the race lock protecting splitPoint access.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With current code we could raise bestValue above beta,
not what is intended for.
Spotted by Richard Vida.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Simplify and streamline the code. Verified all the
resulting bitbases are not changed.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix an issue where the log file stores an incorrect +0.00
eval after a search has been stopped.
Bug reported by Ajedrecista.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This allows to retire ClearMaskBB[] and use just
one SquareBB[] array to set and clear a bit.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With this we should compeltely remove the need
of installing third party POSIX threads library
when compiling with mingw-gcc under Windows.
Spotted by Trung Tu.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is not clear the advantage and we don't want
to risk of introducing regressions on this
very critical parameter. So revert to old limit.
After 16003 games
Mod vs Orig 2496 - 2421 - 11086 ELO +1 (+-3)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Apart from some renaming the biggest change
is the retire of split_point_finished()
replaced by slavesMask flags. As a side
effect we now take also split point lock
when allocation available threads.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of Posix threads. This seems to fix time
losses of the gcc compiled version for Windows.
The patch replaces the MSVC specific _MSC_VER flag
with _WIN32 and _WIN64 that are defined both by
MSVC and mingw-gcc.
Workaround found by Jim Ablett.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of by SEE. Almost no ELO change but it is
a bit easier and is a more natural choice given
that good captures are ordered in the same way.
After 10424 games
Mod vs Orig 1639 - 1604 - 7181 ELO +1 (+-3.8)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
pass references (Windows style) instead of
pointers (Posix style) as function arguments.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The previous line, LDFLAGS += $(CXXFLAGS), does not make sense, and
breaks profile-build, thus changing it into: LDFLAGS += -flto.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Integrate TT_MOVE step into the first state. This allows to
avoid the first call to next_phase() in case of a TT move.
And use overflow detection instead of the bunch of STOP_XX
states to detect end of moves.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In case of a PvNode could happen that alpha == beta - 1,
for instance in case the same previous node was visited
with same beta during a non-pv search, the node failed low
and stored beta-1 in TT. Then the node is searched again
in PV mode, TT value beta-1 is retrieved and updates alpha
that now happens to be beta-1.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Almost no functional change because multiple recaptures
to same square are very rare, but neverthless it seems
the correct thing to do.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
They are almost the same, if the function arguments would
have been the same they could even be integrated.
Also a bit of renaming while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And increase LMR limit. Tests show no change ELO wise,
but we prefer to take the risk to commit anyhow becuase
is a 'prune reducing' patch.
After 10749 games
Mod vs Orig: 1670 - 1676 - 7403 ELO 0 (+-3.7)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Skip calling promotion generation functions in
the very common case of no possible promotion
evasion. Also retire generate_pawn_captures()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix an incorrect warning: 'bm may be used uninitialized'
with the old but still commonly used gcc 4.4
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we don't support anymore popcount detection
at runtime this target is obsolete.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use $(CXX) instead of assuming compiler name is 'gcc'
Spotted by Louis Zulli.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
All the piece dependant data is passed now as
function arguments so that the code is exactly
the same for bishop and rook.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is more correct and specific. Another naming
improvement while reading Critter sources.
No functional changes.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And directly pass RootMoves instead of SearchMoves
to main thread. A class declaration is better suited
in a header and slims a bit the fatty search.cpp
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We just need to verify if a legal move is among the
SearchMoves, so we don't need a vector for this.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
New gcc 4.7 complains about casting a volatile pointer
to void* so assign the variables directly.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It could lead to terrible mistakes otherwise, as
it happened during a game on playchess when on
this position (after white's f4):
2q4r/4b1k1/p3rpp1/3np2p/PpNpNP1P/1P1P2PQ/2P1R3/4R1K1 b - - 0 1
SF moves immediately e5xf4 instead of the correct f5.
In general during engine matches it is impossible the
opponent leaves a piece hanging or anyhow starts a
clear losing sequence. So avoid to fall in subtle traps.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It should help to avoid recalculating check squares
of sliding attackers for queen when already done for
bishops and rooks. Of course this helps when there are
bishop, rook and queen on the board !
Fixed also a subtle bug (use of same variable b in while
condition and in condition body) introduced recently by
revision d655147e8c that triggers
in case we have at least 2 non-pawn discovered check pieces.
This is very rare that's why didn't show in the node count
verification where we actually have a case of 2 dc pieces
in position 14, but one is a pawn.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
During generation of non-captures checks (in qsearch)
we don't consider castling moves that give check,
this patch includes also this rare case. Verified with
perft that all the non-capture checks are now generated.
There should be a very little slowdown due to the extra
work, but actually I failed to measure it. I don't expect
any ELO improvment, there is even no functional change on
the standard depth 12 search, it is just to have a correct
move generator.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The full movegen patch series shows a speed up of almost
6% (!) on perft, and code is much more readable too.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
MV_CHECK is an alias of the more appropiate named
MV_NON_CAPTURE_CHECK so use only the latter.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And make CRITICAL_SECTION locks the only option for Windows.
This guarantees backward compatibility with all the Windows
versions (even XP and older) and an hassle free experience
when compiling for Windows. Tests performed by Ingo and
reported on talkchess confirm there is no speed penalty
against the most modern SRW locks:
http://www.talkchess.com/forum/viewtopic.php?t=41835&start=20
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
On that platform non-bracketed casting are not supported.
Reported by Richard Lloyd.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Further increase safety against time losses. After this
change (tested on LittleBlitzer and cutechess) I had no
more time losses at 2" and 1"+0.02 TC both on Windows
and Linux on more than 10000 games.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We try hard not to lose on time even under extreme
time pressure. We achieve this through 3 different but
coordinated steps:
1) Increase max frequency of timer events
2) Quickly return after a stop signal
3) Take in account timer resolution
With these SF played under LittleBlitzer at 1"+0.02 and 3"+0
without losing on time even one game.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Before creating main thread we set its do_sleep flag to true,
then thread is created and it will go to sleep in main_loop()
after resetting do_sleep.
But if after the setting of do_sleep and before its resetting
the UI thread calls start_thinking() it will not wait on:
if (!asyncMode)
while (!main.do_sleep)
cond_wait(&sleepCond, &main.sleepLock);
as it should but will immediately return before the main thread has
started the search. This very rare race show itself during bench,
when the first position is erroneusly skipped so that bench node count
results of 5309038 instead of the correct 5457475.
The patch is somewhat tricky, but is simple and it works!
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Locals left and right shadow two same named
variables in the std::ifstream base class.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems it yields to missing wake-up events with the
result of SF loosing on time as reported by many people.
So revert the patch and use a more robust approach: assume
there can be spurious wake ups events and make the code to
work also in those cases.
While debugging I found that WaitForSingleObject() had wrong
parameter 0 instead of INFINITE yielding to a crash while
exiting under Windows, strangely unnoticed til now.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The aim is to have shorter names without losing
readibility but, if possible, increasing it.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Retire open(), close() and name() from public visibility
and greately simplify the code. It is amazing how much
can be squeezed out of an already mature code !
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In Windows when OLD_LOCKS is defined we use SetEvent() to mimic
the semantic of the POSIX pthread_cond_signal().
Unfortunatly there is not a direct mapping because with SetEvent()
the state of an event object remains signaled until it is set
explicitly to the nonsignaled state or until a single waiting thread
has been released. Instead in case of pthread_cond_signal(), if there
are no waiting threads it has no effect. What we may want is something
like PulseEvent() instead of SetEvent(). Unfortunatly it is documented
by Mcrosoft as 'unreliable' due to spurious wakes up that could
filter out the signal resetting. So we opt to reset manually any
pending signaled state before to go to sleep.
This fixes the strange misbehaves during 'stockfish bench'
when using OLD_LOCKS under Windows.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that HasPopCnt is a compile time constant we can
centralize and unify the BitCountType selection.
Also rename count_1s() in the more standard popcount()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It was meant to build a single binary optimized
for any kind of CPU: with and without hardware POPCNT.
This is a nice idea but in practice was never used, or
people builds binary with popcnt enabled or not, mainly
according to their type of CPU. And it was also never
used in the official Jim's builds where, in case, would
be easier for a number of reasons, do build two different
versions: with and without SEE42 support.
So retire this feature and simplify the code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This leads to a further and unexpected simplification
of this already very size optimized code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently after a 'quit' command UI thread raises stop
signal, exits from uci_loop() and calls Threads.exit()
while the search threads are still active.
In Threads.exit() main thread is asked to terminate, but
if it is parked in idle_loop() it will exit and free its
resources (in particular the shared Movepicker object) while
sibling slaves are still active and this leads to a crash.
The fix is to let the UI thread always wait for main thread
to finish the search before to return from uci_loop().
Found by Valgrind when running with 8 threads.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Greatly improves the usage. User defined conversions
are a novelity for SF, another amazing C++ facility
at work !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The condition for a mate score was wrong:
abs(v) < VALUE_MATE - PLY_MAX * ONE_PLY
instead of
abs(v) < VALUE_MATE_IN_PLY_MAX
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
During the search we score a mate as "plies to mate
from the root" to compare in an homogeneous way the
values returned by different sub-trees. However we
store in TT a mate score as "plies to mate from the
current position" the let the TT value remain valid
across the game.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is simple but somewhat tricky code that deserves
a bit of documentation. A bit of renaming while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add the check that alpha < beta - 1 if and only if PvNode is true.
The current code would not flag PvNode and alpha == beta - 1. In
other words, the || is not an exclusive OR!.
Also sync assert conditions of search() and qsearch()
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Make a better use of C++ operators overloading to
streamline the APIs.
Also sync polyglot.ini file while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
I am not able to reproduce the speed regression anymore,
and also we were using cout even before speed regression
so probably the reason is not there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Be consistent with the way these operators are defined
in plain C (and in C++).
Spotted by Lucas Braesch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We don't use killers to order evasions, so it
seems natural do not consider an evasion cut-off
move as a possible killer. Test shows almost no
change, as it should be becuase this is a really
tiny change, but neverthless seems the correct
thing to do.
After 11893 games
Mod vs Orig 1773 - 1696 - 8424 ELO +2 (+-3.4)
Idea from Critter.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Take advantage of argument-dependent lookup (ADL) to
avoid specifying std:: qualifier in some STL functions.
When a function argument refers to a namespace (in this
case std) then the compiler will search the unqualified
function in that namespace too.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Partially revert efd2167998
Without this patch SF does not send "bestmove" to GUI.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Seems sensibly faster: On a
./stockfish bench > /dev/null
We have +2% on mingw and even +5% on MSVC !
Also removed the nice but complex enum set960 machinery,
use directly the underlying move_to_uci() function.
Speed regression reported by Heinz van Saanen.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Do not return the book move if is not among the
RootMoves,in particular if we have been asked to
search on a move subset with "searchmoves" then
return book move only if it is among this subset.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Introduce pv_info_to_log() and pv_info_to_uci() and
greatly cleanup this stuff.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Actually after last patch it happens that delta
starts always with the fixed value of 16.
So further remove useless code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems that we just need to look at previous score to
compute aspiration window size.
After 5350 games:
Mod vs Orig 800 - 803 - 3647 ELO +0 (+- 5.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Diretcly use the underlying std::vector<Move> and the
STL algorithms. Also a bit of cleanup while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is ok to redirect st pointer to startState, but the latter
should be updated with the content pointed by the st of the
original position. The bug is hidden when startState and *st
are the same as is the case of searching from start position,
but as soon as moves are made (as is the case when splitting)
the bug leads to a crash.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The Position object used by UI thread is a local variable in
uci_loop(), so after receiving "quit" command the function
returns and the position is freed from the stack.
This should not be a problem becuase in start_thinking() we copy
the position to RootPosition that is the one used by main search
thread. Unfortunatly we blindly copy also StateInfo pointer that
still points to the startState struct inside UI position. So the
pointer becomes stale as soon as UI thread leaves uci_loop() and
because this happens while main search thread is still recovering
after the 'stop' signal we have a crash.
The fix is to update the pointer to the correct startState after
the copy.
Found with Valgrind.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Comments should be informative but not pedantic / obvious.
The only exception is the function description where we
indulge a bit on the "chatty" side, but has always been like
this since Glaurung times, so we continue with this tradition.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Tested togheter with previous patch; shows no regression and
is a semplification.
After 5817 games:
Mod vs Orig 939 - 892 - 3986 ELO +2 (+- 5.1)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Triggered by a comment of Eelco on talkchess. Also
a bit of cleanup while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Consider negative captures as good if
still enough to reach beta.
After 7502 games:
Mod vs Orig 1225 - 1158 - 5119 ELO +3 (+- 4.5)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A cast rarely is the right solution. In this case was enough
to redifine 3 variables with type size_t instead of int
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems we don't have any added value. Note that the
moves that were used to be extended are still flagged
as dangerous so to avoid at least pruning them.
After 9555 games
Mod vs Orig 1562 - 1540 - 6453 ELO +0 (+- 4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
As Heinz says:
"Function empty() should have a constant run-time even
on lousy compilers and you spare the not.
The change is even measurable: + 100-150 nodes/sec. Wow:-)"
Patch from Heinz van Saanen
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is more idiomatic for a functor (a function object) as are
the endgames.
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A pinned piece cannot move and so does not play any role
in SAN disambiguation.
Reported by Steven Edwards.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It was never clear to me why we needed this trick, and now
that we rely only on C++ std::getline() and std::cout for
input / output it is even more a mistery what this code does.
So disable it and wait to see if someone screams ;-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Detach from the UI thread the input arguments used by
the search threads so that the UI thread is able to receive
and process any command sent by the GUI while other threads
keep searching.
With this patch there is no more need to block the UI
thread after a "stop", so it is a more reliable and
robust solution than the previous patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Unfortunatly xboard sends immediately the new position to
search after sending "stop" when we have a ponder miss.
Becuase main thread position is not copied but is referenced
directly from root position and the latter is modified by
the "position.." UCI command we end up with the working position
that changes under our feet while the search is still recovering
after the "stop" and this causes a crash.
This happens only with the (broken) xboard, native UCI does not
have this problem.
Reported by otello1984
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fixes an hang when playing with ponder ON. Perhaps there is still
a very small race but now it seems engine does not hang anymore.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Move global search-related variables under "Search" namespace.
As a side effect we can move uci_async_command() and
wait_for_stop_or_ponderhit() away from search.cpp
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use the starting thread to wait for GUI input and instead use
the other threads to search. The consequence is that now think()
is alwasy started on a differnt thread than the caller that
returns immediately waiting for input. This reformat greatly
simplifies the code and is more in line with the common way
to implement this feature.
As a side effect now we don't need anymore Makefile tricks
with sleep() to allow profile builds.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If we are pondering we will stop the search only when
GUI sends "ponderhit" or "stop" commands or when we reach
maximum depth. In all the other cases we continue to search
so there is no need to verify for available time.
Also better clarify why wait_for_stop_or_ponderhit() before
to exit in some cases.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In case there is only 1 legal move we will stop the
search at depth 10 anyway because the exclusion search
probe will fail low.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In the "easy move" paradigm we verify if the best move has
ever changed over a good number of iterations and if the
biggest part of the searched nodes are consumed on it.
This is a kind of hacky ad indirect heuristic to deduce
if one move is much better than others.
Rewrite the early stop condition to verify directly if one
move is much better than others performing an exclusion
search.
Idea to use exclusion search for time management if form Critter.
After 12245 games at 30"+0.1
Mod vs Orig 1776 - 1775 - 8694 ELO +0 (+-3.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Tuned with CLOP against a pool of 3 engines. Result
verified with a direct match:
After 11720 games at 10"+0.1
Mod vs Orig 1922 - 1832 - 7966 ELO +2 (+-3.6)
So no change in self match but if CLOP is right it should
be a bit better against an engine pool.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The value returned by root search it is actually
our best value, so rename the variable to reflect this.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of binding link time optimization to the choice of
popcount support, do the right thing and add -flto option
when gcc 4.5 or later is detected.
Although it should be supported also under mingw, it happens
that it doesn't, at least on my 4.6.1 due to some known bugs.
Thanks to Mike for helping me with this patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Remove the bonus for no *friendly* pieces in the pawn's path and
reduce a bit the bonus based on kings proximity.
This patch is part of to the ongoing effort to remove form evaluation
all the terms that do not add value.
After 16284 games:
Mod vs Orig 2728 - 2651 - 10911 ELO +1 (+- 3.1)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After a "stop" due to a ponder miss Xboard sends
immediately the new position to search, without
waiting for engine to effectively stop the search.
It is not clear if this is a GUI bug (as I suspect)
or allowed behaviour, but because it won't be fixed
anyway workaround this issue making listener thread
to switch to in-sync mode as soon as a "stop" command
is received.
Thanks to Mike Whiteley for reporting this.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If GUI sends stop while we are waiting for
a command do not reply with a silly:
Unknown command: stop
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Oliver reports profile builds error with new gcc 4.6, he says:
"We need to add -lgov with profile-generate AND profile-use.
So it has to be added to the second stage of building too.
The problem occurred first with the introduction of gcc4.6 and
I think this is because the previous version did find the gcov
library automatically. gcc4.6 needs more precise options and
does less guesses. I have seen it in debian, Ubuntu and also with
mingw on Windows. And all use gcc4.6."
This patch fixes the issue.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After async I/O patches 'bench' changed behaviour and now waits for
input at the end of the test run. This is due to listener thread stay
blocked on std::getline() even after test run is finished, as soon as
we feed something the thread unblocks and then quickly exits.
This is not a big problem, but has the bad side effect of breaking
profile builds that hang forever at the end of the test run.
The tricky workaround is to create a pipe that connects to stockfish
input and then, when test run is finished, breaking the pipe: this
makes std::getline() immediately return.
So this patch adds a 'sleep 10' piped into 'stockfish bench' test run
command. After 10 seconds sleep ends, the pipe breaks and 'bench'
finishes as usual.
Thanks to Oliver Korff for reporting the issue, and to Mike Whiteley
for having co-authored this solution.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use do_uci_async_cmd() instead of process input commands
directly and clarify that what we are waiting for is
something that is able to raise StopRequest flag.
Also fix some stale comments in do_uci_async_cmd(). Here
we need to reset Limits.ponder only upon receiving "ponderhit".
In the case of "quit" or "stop" resetting Limits.ponder has no
effect because the search is going to be stopped anyway.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The timer will be fired asynchronously to handle
time management flags, while other threads are
searching.
This implementation uses a thread waiting on a
timed condition variable instead of real timers.
This approach allow to reduce platform dependant
code to a minimum and also is the most portable given
that timers libraries are very different among platforms
and also the best ones are not compatible with olds
Windows.
Also retire the now unused polling code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With our new listener thread we don't need anymore
this ugly and platform dependent code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of polling for input use a dedicated listener
thread to read commands from the GUI independently
from other threads.
To do this properly we have to delegate to the listener
all the reading from the GUI: while searching but also
while waiting for a command, like in std::getline().
So we have two possible behaviours: in-sync mode, in which
the thread mimics std::getline() and the caller blocks until
something is read from GUI, and async mode where the listener
continuously reads and processes GUI commands while other
threads are searching.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The std::min() template function requires both arguments
to be of the same type.
But here we have the integer MAX_THREADS compared to a long:
long sysconf(int name);
So cast to integer and fix the compile.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add comments and rename stuff to better clarify what the
magic bitboard initialization code does.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We test if the piece moved in 'to' attacks the square 's' with:
bit_is_set(attacks_from(piece, to), s))
But we should instead consider the new occupancy, changed after
the piece is moved, and so test with:
bit_is_set(attacks_from(piece, to, occ), s))
Otherwise we can miss some cases, for instance a queen in b1 that
moves in c1 is not detected to attack a1 while instead she does.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is not possible to unify due to the fact that the
sequence steps are reversed. What we can do is to try
to sync comments and code as much as we can to easy
reading and documentation.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is called only in do_move() that now has been fully
expanded. This is the most time consuming function of
all the engine.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Is called in just one place. And rename set_castle() in the
now free to use and more appropiate set_castle_right().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
They don't add any value given that the corresponding
table has global visibility anyhow.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is a prerequisite to allow changing piece values
at runtime, needed for tuning.
Also use scores instead of separated midgame and endgame values.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
First tuning with CLOP against a pool of 3 engines. Result
verified with a direct match:
After 8736 games at 10"+0.1
Mod vs Orig 1470 - 1496 - 5770 ELO -1 (+-4.3)
So no change in self match but if CLOP is right it should
be a bit better against an engine pool.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In particular add that we can have an harmless false positive
in case StopRequest or thread.cutoff_occurred() are set.
Reported by David Lee.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
As a side effect now log file is open and closed every
time it is used instead of remaining open for the whole
thinking time.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Mainly used to log stuff to a file while playing, when
stdout is used for the comunication with the GUI.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Build broken by commit 3141490374
where we renamed move_is_ok() in is_ok() and this clashes
with the same named method in Position that overrides the
move's one causing compile errors.
The fix is to rename the method in Position.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Justin reports that it breaks the compilation on Fedore 15 and as Tom says:
-static is only needed to work around the gcc on ubuntu 11.10 beta bug.
If -static introduces issues on its own then it is better to remove it.
It will not be needed in most environments.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Partially revert 1036cadcec because UCI protocol
in case of multipv explicitly requires:
for the best move/pv add "multipv 1" in the string when you send the pv.
in k-best mode always send all k variants in k strings together.
Thanks to Justin Blanchard for pointing this out.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is enabled when selecting x86-64-modern target, this gives
another nice speed up:
On a Core i5-2500 (3300 Mhz, Sandy Bridge):
64 bit download version: 1597151 n/s
-flto : 1659664 n/s
-flto -msse3: 1732344 n/s
Patch suggested by Tom Vijlbrief.
Also unify flto, popcount and msse3 optimization under "modern"
target, note that this can break the "modern" build on old gcc that
do not support -flto option: in this case update gcc ;-) or default
to the standard build.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Just by adding the -flto option to CXXFLAGS link command
we can gain a few percent in speed.
On a Core i5-2500 (3300 Mhz, Sandy Bridge):
64 bit download version:
Without -flto: 1597151 n/s
With -flto : 1659664 n/s
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This was not clear to someone on talkchess and actually
is not trivial to understand.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems we have a very rare crash under Linux, once
every 10K games without this patch.
Is faster to wake up all the threads, especially on SMP,
where the threads can then exit in parallel while the main
thread is waiting for the next one to terminate.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Almost no increase but seems the logic thing to do.
After 16707 games 2771 - 2595 - 11341 ELO +3 (+- 3.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Restore old locking scheme changed with
commit 1e92df6b20.
This seems to prevent a very rare crash that occurs
once every 5-10K games.
With this patch we have no crashes after 33K games.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is more natural than using the family subtype and also
use two single maps instead of a std::pair.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When initializing endgames map we build a faked FEN string
in mat_key() to get the position hash's key.
This fen string lacks full move numbers, so when parsing the
fen in Position::from_fen() we leave startPosPly un-initialized.
Spotted by Valgrind (this is a kind of bug that is almost impossible
for humans to find).
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Another stupid remark to quiet out:
remark #2259: non-pointer conversion from "int" to "UINT16={unsigned short}"
may lose significant bits
In this case icc always converts to an integer the result of a shift operation
if the bit size of the operand is smaller, hence the warning when assignin
back to n.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we have just two mutually exclusive thread's states
we can repleace them by a simple boolean.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that Rml ordering is based on normal MovePicker logic,
apart for the ttMove that is given, we can avoid to score
all the root moves at depth 1. We only need it for easy move
detection logic, but in this case we just need to score the
first two best moves and not all the Rml set.
No regression after 6400 games
Mod vs Orig 1052 1012 4336 ELO +2 (+- 4.9)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Allocation of pawn and material hash tables should
be strictly bounded to the change of the number of
activeThreads, so move the code inside set_size().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use proper way to detect for thread terimnation instead of
our homegrown flag.
It adds more code than it removes and adds also platform specific
code, neverthless I think is the way to go becuase Thread::TERMINATED
flag is intrinsecly racy given that when we raise it thread is still
_not_ terminated nor it can be, and also we don't want to reinvent
the (broken) wheel of thread termination detection when there is
already available the proper one.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Was used to prevent issues when creating multiple threads
on Windows, but now it seems we can remove it safely.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we can split at root it happens that SendSearchedNodes
works only once at the end of the iteration, but this is useless
becuase speed info is sent anyhow toghter with the pv line.
So retire for now, waiting to find something SMP compatible.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Change qsearch() to reflect alpha update logic
of search().
To be consistent changed also moves loop condition and
futility pruning condition.
No regression after 5072 games at TC 10"+0.1
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Start a slave as soon as is allocated.
No functional change with faked split.
Regression tested the full split() series and after
2000 games no regression and no crash.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When calling split or we immediately return because unable to
find available slaves, or we start searching on _all_ the moves
of the node or until a cut-off occurs, so that when returning
from split we immediately leave the moves loop.
Because of this we don't need to change alpha inside split() and
we can use a signature similar to search() so to better clarify
that split() is actually a search on the remaining node's moves.
No functional change with faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Allocate and initialize a new split point
out of lock becuase modified data is local to
master thread only.
Also better document why we need a lock at
the end of split().
No functional change with faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When StopRequest is raised we cannot immediately exit the
move loop but first we need to update bestValue so to avoid
assert:
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Another great success by Joona !
After 5876 games at 10"+0.1
Mod vs Orig: 1073 - 849 - 3954 ELO +13 (+- 5.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we don't special case the root moves anymore
we don't need to pass NodeType anymore as template parameter,
a simple bool to detect a SpNode will be enough.
Spotted by Joona.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After issuing "go"-command, at the end of the search
SF shows: "Unknown command: ...".
Spotted by Joona.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of our home grown function to perform a case
insensitive compare on option names as required by UCI
protocol.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems FritzGUI already remembers the old lines, so
we just need to update PV info only for the new lines.
Also introduced prevScore field in RootMove to avoid
a bulk copy of Rml.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This should fix following issue:
Suppose the search with MultiPVIteration == 0 returns an exact score
move = Nxf4, score = 100
Now search with MultiPVIteration == 1 and get two scores
move = Qg8, score = 150
move = Ra1, score = 180
If we now reorder all the moves in one step we end up with
pv[0] = Ra1, pv[1] = Qg8
Instead reordering as the current patch we end up in:
pv[0] = Ra1, pv[1] = Nxf4
preserving the first searched move.
No functional change in single PV.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This patch temporarily breaks MultiPV and searchmove
features, but they will be re-implemented in future
patches.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We missed to set chess960 flag into the std::stringstream used to
setup the PV line.
Bug introduced with commit f803f33e63
of 30/12/2010 when we started to print PV line into a std::stringstream
instead of directly into cout, where the chess960 flag is correctly set.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
As a side effect now root position can be directly
allocated on the stack and doesn't need to be defined
static anymore.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is misnamed because it is not a parser, perhaps a
tokenizer, anyhow better call it for what it is, an
input string stream.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Return the correct number of played plies at the end
of the setup moves. Currently it always returns 0 when
starting from start position, like in real games.
We fix this adding st->pliesFromNull that starts from 0
and is incremented after each setup move and is never
reset in the setup phase but only once search is started.
It is an hack because startpos_ply_counter() will return
different values during the search and is correct only
at the beginning of the search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This fixes a regression on real games due to the fact that
we have some mismatches:
history[st->gamePly - i] != stp->key
when st->gamePly - i == 0,this is due to a nasty bug I have
introduced when using std::vector<> as StateInfo backup. The
point is that StateInfo keeps inside a pointer to the previous
StateInfo in a kind of linked list. But when std::vector<> is
resized reallocates a larger chunk of memory and moves the
data there so these pointers became stale.
This patch fixes the issue.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We just need startup value to calculate available
thinking time. So remove from state.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Avoid the ugly and anyhow incorrect hard limit on the
maximum number of moves and allow to handle an arbitrary
number of moves to search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This allow to retire do_setup_move() and also to simplify
draw detection logic becuase now we always have:
Min(st->rule50, st->gamePly) = st->rule50
This was already true when starting from starting position,
but now is true even when starting from a FEN string because
now we take in account fullmove number in counting gamePly so
that it is always.
st->rule50 <= st->gamePly
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fixes the reported KNNK ending problem:
http://talkchess.com/forum/viewtopic.php?t=39347
Joona says:
Now I finally had a time to take a look at on this issue.
I've reproduced the problem starting from this position:
1B6/1B2k3/P7/1P3p2/1K6/8/4b3/4b3 w - - 6 85
I made Stockfish play as white and Fruit as black.
I repeated test ten times and once SF was not able to deliver mate.
But I observed several times that SF had reported on last something like mate in 10.
However next time it played move with score mate in 15.
Easiest way to solve the problem is attached as a patch. I tested it several times and SF always
ended up playing the optimal move. Of course the downside is that now delivering mate
takes a bit longer, but IMO it's better to lose once in a while by time in sudden death
game than not being able to deliver simple mate with long time controls.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We have a bug (possibly because of returning draw from
root move list), it is possible to see when looking at
games with a GUI, we can see rarely but consistently the
score return as #0 for many depths until it comes back to
normal values.
Revert patches until it is not fixed.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Running following command:
position startpos moves e1e8
Makes SF to assert in debug mode in do_move() but to accept
bad input and continue in release mode where probably it is
going to crash little later.
So validate input before to feed do_move().
Suggestion by Yakovlev Vadim.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It's only necessary to do the checking at the end of every non-const
member (including the constructors and from_fen()) of class Position.
Once the post-condition of every modifier guarantees the class invariant,
we don't need to verify sanity of the position as preconditions for outside
callers such as movegen, search etc. For non-class types such as Move and
Square we still need to assert of course.
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After previous patch is no more needed to pass
the color, becuase it is always the side to move.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It worked by accident because we always called both directions,
but definition was wrong.
Functional change due to different generation order, but
perft numbers are the correct ones.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Functional change due to the fact that now pick_best() is
stable, but should be no change in strenght.
Example code and ideas by Rein Halbersma.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And pass correct currentPly to TimeManager::init().
This restores old behaviour, in particular now black has
a different timing than white becuase is no more:
currentPly = 2 * fullMoveNumber;
but becomes
2 * (fullMoves - 1) + int(sideToMove == BLACK)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
No functional change also in faked split mode
To be sure verified in real games with 4 threads TC 2"+0.1
After 11125 games 2497 - 2469 - 6159 ELO +0 (+- 4.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix also an incredible 3% speed regression by an almost
never called function. I guess this is due to mingw very low
quality standard libraries implementation.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And also tolerate a 0 value for full move number.
Revert BUG_41 patch, now we set initial King file only
if a castling is possible, so we don't need the fix
anymore in case of correct FEN.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If we cannot castle castleRightsMask[] could be not valid,
for instance when king initial file is FILE_A as queen rook.
In this case castleRightsMask[] at initialQRFile is different
from the expected (ALL_CASTLES ^ WHITE_OOO).
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
See:
http://talkchess.com/forum/viewtopic.php?t=39327
After 8130 games on QUAD at 20"+0.1
1342 - 1359 - 5429 ELO +0 (+- 4.4)
Tried also version with just king settings changed:
After 5932 games 962 - 1052 - 3918 ELO -5 (+- 5.2)
And with just mobility settings changed:
After 4114 games 618 - 619 - 2877 ELO +0 (+- 5.9)
Frank has tested only 1200 games, but at longer TC and
against many engines, so because PHQ results are not worst
than other combination and not worst than original let's
commit his version.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We miss to account as a capture a promotion capture !
Incredible bug in this critical function that is here
since a long time (b50921fd5c of 21/10/2009 !!)
This patch fixes the bug and readds the faster
move_is_capture_or_promotion() that slightly increases
overall speed.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is now much more modular than before and also we
always send the seldepth when we send the depth, this
avoids to make seldepth disappearing from GUI at the
start of a new iteration.
Print also fails high/low pv lines at high enough
search depths.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Easy, almost trivial simplification, I don't understand
how I missed this before !!
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This trivial change gives an impressive 2,5% speedup !!!!
Also retire one unused move_gives_check() overload.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Restore original behaviour, before root unification and
remove a now useless ugly hack for alpha in multi-pv case.
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is not correct to use an iterator stick on a vector that
is sorted becuase iterator is invalidated in general case.
It happens to work by accident because iterators are implemented
as pointers and so they behave in the same (correct) way then
using array indices, but the latters are the correct thing to use.
Also better document the code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is a fossil from the root_search() era, no more
needed today.
Spotted by Onno
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This avoids search explosion in qsearch for some
patological cases like:
r1n1n1b1/1P1P1P1P/1N1N1N2/2RnQrRq/2pKp3/3BNQbQ/k7/4Bq2 w - - 0 1
After 9078 games 20"+0.1 QUAD:
Mod vs Orig 1413 - 1319 - 6346 ELO +3 (+- 4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The trick is to classify more position at first cycle,
so to reduce following work. Speed up is of about 50% !
Also some cleanup while there.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Seems there is no regression so prefer to prune less.
After 8278 games
Mod vs Orig 1246 - 1265 - 5767 +0 ELO (+- 4.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We should start from i = 0, it works by accident because
static storage BSFTable[] is init to zero by default.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In case we have more than one promotion move, prefer
the one that captures the biggest piece.
Almost no functional change, anyhow I don't expect any
ELO change, it is just the correct thing to do.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems much worst in number of nodes seacrhed to reach
the depth and anyhow does not give any advantage to the
Onno's oroginal one.
So revert by now and perhaps readd when we find something
clearly better.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Allow to choose among 4096 instances of pseudo-random
sequences instead of the previous 64 so the probability
to find a better sequence increases and actually we have
a much better 64 bit case and we can also use the 64 bit
version of pick_magic() also for 32 bits and althoug sub
optimal, because now we can have more choices results are
even slightly better also for 32 bit.
Use also a faster submask().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After 12613 games at 20"+0.1 on QUAD
Mod vs Orig 1870 - 1863 - 8880 ELO +0 (+- 3.3)
So no performance change but it is a code semplification
and also is more easy to understand.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Good result for 32 bit case where computation is very fast,
still not satisfying on 64 bit case where the magics seem
a bit harder to get.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Due to a -2% speed penalty. This patch takes the best
of the previous series without the regression due to
introduction of Magic struct.
Speedup against previous revision is of almost 3% !!!!
No functional change both in 32 and 64 bits.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We can calculate them counting the masks bits.
Also small tweak to sliding_attacks()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Here the idea is to test probcut not only after bad
captures, but after any bad move, i.e. any move that
leaves the opponent with a good capture.
Ported by a patch from Onno, the difference from
original version is that we have moved probcut after
null search.
After 7917 games 4 threads 20"+0.1
Mod vs Orig: 1261 - 1095 - 5561 ELO +7 (+- 4.2) LOS 96%
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We really want PV moves and also Split Point moves to be
legal to avoid messing the move counter and corresonding
PV move detection or shared Split Point's counter variable.
This fixes a real bug where a position with only one move
allowed returns bestValue == -VALUE_INFINITE if the move
turns out to be illegal.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We disjoint pseudo legal detection from full legal detection.
It will be used by future patches.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When we are in check and we move the king then testing with
pl_move_is_legal(m, pinned) is not enough becuase we cannot
rely on attackers_to() but we have to explicitly remove the
king form the occupied bitboard to catch as invalid moves like
b1a1 when opposite queen is on c1.
Our move generator already produces correct evasions so we
just need to add the extra verification to move_is_legal().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Found another missed control in move_is_legal() thanks to
brute force testing.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add a new check in move_is_legal()
Avoid useless casting in move.h while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is interesting the fact that we need to test for
move_is_castle(m) anyway and not relying on testing
if destination square is attacked. Indeed the latter
condition fails if the castling rook is attacked,
castling is coded as "king captures the rook" but it
is legal in that case.
Verified no functional change with beginning of the series.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Remove the check for castling moves because it is
already implicit in the check for king moves and castling
is so rare that doing the check is just a slow down.
Thanks to Marek Kwiatkowski.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The structure of move is changed so should also the two
functions. It happens that it works by accident !
Bug spotted by Marek Kwiatkowski
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We already test this condition in see_sign() and
so it is almost always a redundant verification.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Bug is subtle because appears only under MSVC 32 bits in
optimized version, hence was missed before.
Bug is due to the fact that evaluation order of terms of a
sum is undefined by the standard, so in get_int() we have:
return 256 * get_int<n-1>() + bookFile.get();
And if get() is evaluated before get_int() we have a corrupted
key.
The patch rewrites the code in a more natural and predictable way.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If blockSq is already on rank 8, blockSq + pawn_push(Us) is on rank 9,
outside of board. It does not make sense to measure king distance to
a field outside the board.
Bug spotted by Fruity:
http://open-chess.org/viewtopic.php?f=5&t=1156&start=10
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Almost useless for the user and now is in sync with
the material value that is already weighted.
A small speedup of 0,4% because we avoid an apply_weight()
call in a fast path.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also simplify tracing because evaluate_unstoppable_pawns()
return always zero if both colors have non pawn material.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Extensive test series on tweaking history limit and bonus
formula. At the end this was the best.
After 11959 games:
Mod vs Orig 2087 - 1934 - 7938 ELO +4 (+- 3.7) LOS 92%
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Node count is different just becuase now we don't log on
"bench.txt" file anymore so that we avoid some calls to
pretty_pv() that calls Position::do_move().
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This prevent crashing on mobile devices with limited RAM,
currently with MAX_THREADS = 32 we would need 44MB that
could be too much for a poor cellphone.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This change allows to remove some quite a bit of code
and seems the natural thing to do.
Introduced file thread.cpp to move away from search.cpp a lot
of threads related stuff.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
According to Heinz's tests current setup is in fact too
strong for weak players. This seems the best according
to his tests.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems gain is practically unuseful, so remove.
After 13554 games:
Mod vs Orig 2252 - 2319 - 8983 ELO -1 (+- 3.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Shrink search() signature for better readibility.
We get also a nice 1.3% speed increase.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Unfortunatly icc does not understand that weakerSide and
strongerSide belongs to the base class :-(
So we have define them in the derived class.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we prefetch in material hash table we
can increase its size and gain something.
Hit rate is now of 98% from 92%
Speedup of 0.8%
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Prefetch both pawn and material tables in do_move() and
prefetch always, not only after a pawn move or a capture.
Speed up of 0,7%
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The only interesting thing is that a backward or isolated
pawn cannot be a candidate passer, so code this condition.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems we have a lot of totally useless code !
After 8577 games 1504 - 1451 - 5622 ELO +2 (+- 4.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add blunder cabability to skill level feature.
The idea is that instead of choosing the best move at the end
of the ID loop, we now do this at a randomly chosen sampling depth
dependent on SkillLevel, so that at low skill levels we sample when
ID loop has reached only a small depth and so we have an higher
probability to pick up a blunder.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The idea is to try a shallow search with reduced beta
on bad captures so to quickly prune them out in case
are really bad.
After 5529 games 966 - 868 - 3695 ELO +6 (+- 5.4) LOS 91%
Tested also version without upper limitation to 8 plies:
After 8780 games 1537 - 1398 - 5850 ELO +5 (+- 4.3) LOS 93%
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Rescaled Skill level from 0 to 20. At level 19 is still
comparable with Crafty 20.14, while at low levels strength
increase is now less steep.
Thanks to Joona and Heinz for testing and valuable
comments.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is now possible to adjust skill level of Stockfish
from 10 (full strength) to 0.
Skill adjustment is done in such a way that is CPU speed and
time control largely independent, at least at low skills. It
means that given a skill we have same play level on a mobile
phone and on a super OCTAL CPU, at 1' per game or at 180'.
At skill 9 strength is that of an average engine, I have used
Crafty 20.14 to tune and we are more or less there. At skill 0
engine is pretty weak but still shows a realistic play.
When skill is not used we don't have any impact on the regular
code.
Idea to use MultiPV is from Heinz van Saanen, implementation and
formulas by me.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is how Shredder, Rybka and others do and
avoids user is confused by a fail high (sent to GUI)
followed by a fail low (not sent).
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Has been reported by Justin Blanchard that
this creates problems on some buggy GUI.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With off-by-one bug in InFrontBB[] loop fixed.
Also use int instead of File to workaround a bug
in mingw 4.4.0 in first loop that cycles forever.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
No speed regression after 8731 games:
Mod vs Orig 1394 - 1342 - 5995 ELO +2 (+- 4.1)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Otherwise in case we change an option with setoption and
then ask for "eval" command the evaluation is not updated.
Spotted by Justin Blanchard.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix a corner case where we start aspiration window and
suddendly we get a VALUE_KNOWN_WIN / MATE score, this makes
aspiration to blow up in a series of researches loops.
Exit aspiration loop in that case.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use first iteration to get a proper startup score
and possibly detect an easy move.
After 5180 games:
Mod vs Orig 847 - 823 - 3510 ELO +1 (+- 5.5)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Because we are never in check there and evaluation cannot
return a mated value the condition is useless.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This patch is based on Justin Blanchard's original
work and allows to breakdown evaluation in its sub terms and
show to the user.
Tracing code has zero speed impact when not used.
Note that tracing code is not thread-safe, but this
should not be a problem given the typical usage scenario.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use Square instead. At the end is the same because we were
anyway foreseen operators on mixed terms (Square, SquareDelta).
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we don't have anymore a search stack array in
SplitPoint we can rename this data member to somthing more
usual.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use a local variable instead. To make it work we need to
correctly init next ply search stack at the beginning of the
search because now that ss is allocated on the stack instead
of on the global storage it contains garbage.
As a side effect we can peform a fast search stack
init in id_loop().
With this patch size of SplitPoint goes from 71944 to 136 bytes,
and consequently size of Thread goes from 575568 to 1104 bytes.
Finally the size of ThreadsManager that contains all the thread
info goes from 9209248 to just 17824 bytes !!
No functional change also in faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This allow us to restore the old depth 12 benchmark
and fixes one and for all the depth mess.
Test confirms no regression:
After 5658 games 892 - 924 - 3842 ELO -1 (+- 5.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Note that this introduces an asymmetry in which best move
is searched deeper then others also in MultiPV, but this is
not an error per se.
No functional change when MultiPV = 1
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This patch removes a condition that allows a PV entry to remain
in TT across games for an unlimited time.
Although this produces a nice ELO boost in the long term it
is an artifact that affects tests results bewteen version
with and without this feature.
So remove now and readd before to release because it actually
seems a strong feature.
As example a verification tournament against SF 2.0.1 starting around
+10 ELO after 4K games sligltly climbed to +21 ELO after 14K games !!!
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Skip writing fail high/low sequences. Note that we don't need
fail high/low markers anymore in pretty_pv().
No functional change but some do/undo move sequences.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
First search should be done at iteration = 1, not 2. So offset
the variable by one.
As a nice side effect now search correctly stops at PLY_MAX
included, not after searching (PLY_MAX - 1) as before.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Interestingly this patch will make people complain search depth
is reduced against 2.0.1 ;-) but actually it is only an artifact.
Spotted by Joona.
No functional change apart from a different do / undo move
sequence due to teh fact that we don't call pv_info_to_uci()
anymore before entering id loop.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
No functional change apart form move reordering because
pv_info_to_uci() performs a do / undo_move sequence.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Biggest advantage is be able to analize positions
without "loss of memory" when goind back/forth in
a position.
Patch has proven to fix analysys problems and is even
worths some elo points.
After 5811 games Mod- Orig:
1037 - 902 - 3872 +8 ELO (+- 3.6) LOS 97%
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Warning C4146: unary minus operator applied to
unsigned type, result still unsigned.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We dont' call MovePicker from print() anymore, so that
reentrancy check in now not needed.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This let us get rid of number_of_evasions()
After 5487 games
Mod- Orig: 851 - 852 - 3784 +0 ELO (+- 3.7)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Move qsearch scoring functionality out of RootMoveList
initialization. Will be needed by future patches.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is used for secondary scoring so it does not
changes the fact that Rml[0].pv[0] is always tried
as first anyhow.
It happens this is even a no functional change patch
becuase we reinsert PV in TT after a search so that
TT move is actually Rml[0].pv[0].
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So to better spot where the differences really
count. Also add some more additional cleanup.
Harmless functional change and no regression.
After 5780 games
Mod- Orig: 931 - 955 - 3894 ELO -1 (+- 3.6)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In case of a Root node we can leave with bestValue set
to -VALUE_INFINITE if search is stopped by the GUI and
stopReques flag is raised.
This patch fixes the issue.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A bit of template magic to restore a proper and readable moves
'while' loop that now is again 'similar' to the one that used
to be in search().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Teach search() to behave as a root node if requested.
Just added code, but still no functional change.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And sync root_search() with search()
After 9384 games Mod - Orig:
1532 - 1433 - 6419 ELO +3 (+- 2.8)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Returns an int64_t while we want a simple int.
This occurs only when compiling with MSVC on a 64 bit platform.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Respin this old idea. Earlier we tried only
with < 1000 games and result was inconclusive.
After 5845 games
Mod vs Orig: 935 - 936 - 3974 ELO (+-3.6)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If size_t is defined as a 32 bit quanitity then we have an
overflow in the left term of the while condition if mbSize
is bigger then 2048.
For instance if mbSize is 2049 then when newSize will reach
0x80000000 (2048MB) comparison is still true, 'while' loops
again and we have an overflow in the expression (2*newSize)
so that result is 0 and at that point 'while' keeps looping
forever hanging the application.
This patch fixes the bug and also makes operator new do not
throw an exception upon failure but return a NULL pointer
instead.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In input_available() we use function select(), so
we have to set as unbuffered also C library I/O
functions otherwise we can miss some input.
For instance in case GUI sends "go infinite\nstop\n" we
parse the "go infinite" but then input_available() under Linux
is unable to detect that we still have "stop" to be processed.
This is because "select" uses file descriptors instead of file
pointers. So it cannot know about the buffer associated to a file
pointer.
This patch, by BB+, should fix the problem.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also let do_setup_move() don't reuse same StateInfo so that
we can remove the check about different StateInfo objects
before memcpy() in do_move.
Functional change due to harmless additionals
do_move() / undo_move() steps.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Actually it is san.cpp renamed. Because now has the move
conversions functions and doesn't have any more the bulky
move_from_san(), it is better to call it move.cpp
Remove san.h while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use a reverse logic: among the list of generated legal moves
transformed in UCI coordinate notation find the one that
matches the given string.
It is a bit slower, but here is not performance critical and
is much more simplified then before.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This partially reverts 1e7aaed8bc keeping the conversion
functions from/to move to uci string in the same file.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
I got report from Werner that Shredder Gui has problems with
UCI values which maximum value is greater than 30000.
Of course it's stupid to change engine to fix a GUI's bug,
but on the other hand 30000 ms as maximum value is clearly enough,
so why not to be merciful
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Added checking of (stdin->_cnt > 0) from Greko.
This seems to greatly improve responsivness when running
under console. Now while running a 'stockfish bench', any key
press immediately is detected by SF while before there was a
delay of some fraction of a second.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is an old Glaurung bug that prevented a Polyglot
book move to be read correctly in case of underpromotion.
This patch fixes the bug restoring support for both
queen and underpromotions.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
MSVC (and possibly other compilers) does not inline
as requested, so force it to do so.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Move the castling condition test out of the
function. This avoids a function call most of
the times.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Functional change due only to moves reorder. Anyhow after
5242 games at 15"+0.1 TC verified we have no regression.
Mod vs Orig 994 - 958 - 3290 +2 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Shrink of 1 bit so to fit a move in an uint_16 and
possibly a MoveStack in an uint_32.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A bit faster on 32 bits machines, more similar to
TranspositionTable::first_entry() and same result.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
There was a strange "int16" type and "int64_t"
was defined twice.
Spotted by Joona.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We never reach a position where rule50 > 100.
When rule50 == 100, it's either draw or mate and
there is no way search could go deeper.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We must be able to filter out also moves where move_is_ok()
is false.
And actually we are. Tested on all the default position injecting
a number from -1000000 to 1000000 casted to a Move.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
As is defined now is always true, tested with:
for (long i=-1000000; i < 1000000; i++)
if (!move_is_ok(Move(i)))
exit(0);
Reason is that move_from() and move_to() already truncate the
input value to something in the range [0, 63] that is always
a possible square.
So change definition to something useful.
The same applies also to square_is_ok()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now first move has moveCount == 1 also in root_search()
Also added small readibility touches.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Should be already inlined by the compiler when
optimizing but better safe than sorry ;-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Keep the isChess960 flag inside Position so that is
copied with the Position, but esplicitly highlight the
fact that a FEN string has not enough information to detect
Chess960 in general case. To do this add a boolean argument
isChess960 to from_fen() function so to self document this
shortcoming of FEN notation.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems HP's ANSI C++ doesn't understand very well
standard function-style cast.
Reported by Richard Lloyd.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And set them as default.
Introduce compile switch OLD_LOCKS to allow to fallback on
compatible locks supported by Windows XP and older versions.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Introduced by me in before 1.9 and found by Tord that says:
The 'isChess960' slot in the 'Position' class is currently
set depending on the initial files of the rooks, and not on the value
of the UCI_Chess960 parameter. This is incorrect, as there are lots of
Chess960 positions where the rooks start on the usual files. As a
consequence (unless I am missing something), Stockfish will occasionally
output castling moves as e1g1/e1c1 rather than the correct e1h1/e1a1 format
in Chess960 games. It is possible that some or even most GUIs are robust
enough to accept both notations, but I wouldn't bet on it. And in any case,
Stockfish's behavior clearly violates the protocol.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This time I have removed the function alltogether !
Sorry to work above a patch of UncombedCoconut (Justin Blanchard)
but I couldn't resist ;-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When we log best and ponder move to a file before to
return from think we change the position. If position is
then not resended by GUI, as for manual user input we got
an error:
justinb@malibu:~$ stockfish
Stockfish 2.0 JA 64bit by Tord Romstad, Marco Costalba, Joona Kiiski
setoption name Use Search Log value true
go depth 1
info depth 1
info depth 1 seldepth 1 multipv 1 score cp 72 time 59 nodes 20 nps 338 pv g1f3
info depth 2
info depth 2 seldepth 2 multipv 1 score cp 12 time 59 nodes 44 nps 745 pv g1f3 g8f6
info nodes 84 nps 1423 time 59
bestmove g1f3 ponder g8f6
go depth 1
info depth 1 score mate 0
info nodes 87 nps 0 time 0
bestmove (none) ponder (none)
Bug spotted and fixed by UncombedCoconut.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And set "Use Sleeping Threads" to true because it keeps
much more responsive and cool my QUAD during tests :-)
It will be reverted back before to release that's the
reason to bundle it here.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Always same siganture: 7224363
Hopefully some more bug fixed and restored
compatibility with WIndows XP.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
They are not compatible with Windows XP
Revert to old CRITICAL_SECTION locks and events.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Second parameter of insertion_sort() is a pointer to the
element _after_ the last of the list, e.g. end() when sorting
all items.
If we want to sort say the first 2 moves we should write:
sort_multipv(2);
So, becuase in root moves loop move counter 'i' starts
from 0, we need to pass:
sort_multipv(i+1);
To sort up to move 'i' included.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It doesn't seem to have any meaning.
Also add a FIXME on the MaxNodes condition that now is broken
in SMP case due to known issue with pos.nodes_searched()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We were not quitting the engine after a "quit" command
while still in the book and pondering.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If flag StopOnPonderhit is set it means that we UseTimeManagement
and also we are at Iteration >= 3.
So we can safely simplify the formula.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is called only from one place, so move code there.
Add a bit of renaming and documentation while at there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And set "Use Sleeping Threads" to true because it keeps
much more responsive and cool my QUAD during tests :-)
It will be reverted back before to release that's the
reason to bundle it here.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It was introduced by patch 66d16592 of 22/3/2009 merging
from Glarurung iPhone.
Tord says:
That change is only found in the Glaurung iPhone app, and not
in the latest Glaurung UCI source code. I don't remember why
this was added (and the iPhone app, unlike the UCI engine,
was never version controlled), but it was almost certainly
because it was somehow needed in the communication between
the engine and the iPhone GUI, and that it was never meant to be
included in the UCI engine. My guess is that it has something to
do with castling moves being entered as e1-g1 in the GUI, but
represented as e1-h1 in the chess engine.
Removing it in Stockfish should be completely safe, and won't harm
the iPhone version. Initially the iPhone GUI called functions in the
chess engine for checking for legality of moves, writing the move
list in SAN format, and various other tasks, but this is no longer
the case in the current version.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is the "selective search depth in plies" and we set
equal to PV line length.
Tested that works under FritzGUI.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems a more appropiate place (IMHO) and helps to clarify
that idle_loop() should return a move, not a score.
Fix also handling of stalemate positions (we were not
sending any score) and we don't need to wait on "ponderhit",
this is done when returning in think().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We have a small functionality change in case we have a
fail-high so that both rml[].pv and pv[] are updated, but if,
after researching, we have a fail-low then rml score is updated
again but pv[] remains the same and coming back from search we
used a PV line that has failed-low (after having failed-high).
With this patch we always use the 'correct' PV line, i.e. the
line with highest score at the end of the whole search.
Retire also redundant RootMove's 'move' member and directly
use pv[0] instead.
Define symbol '<' to mean 'minor of', as it should be. Its meaning
was reversed to be used with std::sort() that sorts in ascending order
while we want a descending order.
But now that we use our own sorting code we don't need this
trick anymore.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When a reference breaks things !
Here we take a reference (that is a pointer) to an
entry in a vector that changes below us --> BOOM !
References are essential but should be considered with
care in C++ because could lead to nasty surprises.
Restored functionality.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of a default member by member copy use set_pv()
to copy the useful part of pv[] array and skip the remaining.
This greatly speeds up sorting of root move list !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is redundant being a move list ;-)
Also better document the two scores used by root list.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Function ray_bb() was used just in one endgame where can
be used squares_in_front_of() instead.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Remark 1418: external function definition with no prior declaration
and
Remark 1419: external declaration in primary source file
Can be safely ignored because are pure idiocy.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Namely we use only two types of depth in TT:
DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And rename move_from/to_string() in a more specific
move_from/to_uci() that is a simple coordinate notation.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use one sleep lock per thread insted of a single one shared.
Also renamed WaitLock in SleepLock.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
By mean of an an UCI option it is possible let the available
threads to sleep, this should help with Hyper Threading although
is not the best solution when number of threads equals number
of available cores.
Option is disabled by default.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
No speed regression and no functional change.
After 7826 games Mod- Orig:
1188 - 1230 - 5408 ELO -1 (+- 3.1)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Non-PV LMR is left unchanged.
After 8819 games
Mod- Orig: 1442 - 1343 - 6034 ELO +3 (+- 2.9) LOS 86%
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Bug introduced in 9dcc2aad98
We can be asked to open a non-exsistent file,
in this case we should gracefully handle the
case and silently return instead of exiting.
Bug discovered and bisected down by Joona.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This time we try very hard to avoid false positives.
The obvious downside is that we also miss many true
winning positions.
After 10544 games on RC
Mod- Orig: 1744 - 1646 - 7154 ELO +3 (+- 2.7) LOS 83%
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After 2036 games Mod- Orig:
381 - 278 - 1377 ELO +17 (+- 6.2) LOS 99%
One of the biggest increases ever !
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When MultiPV > 1, always take bestmove from the RootMoveList
(and don't bother with a ponder move). Without that the bestmove
is most probably incorrect.
Patch from Peter Petrov.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When we store this value in TT we cut this to 9 bits,
so we need a smaller variable otherwise comparisons
like:
replace->generation() == generation
Are always false if generation is bigger then the maximum
TT storable value.
This fixes a very nasty and difficult to spot bug (2 weeks for
regression hunting).
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is a redundant boiler plate, just call initialization and
resource release directly from main()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Correctly handle uci option names in a case insensitive way.
Alos fix some indentation while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Was introduced by 403db5a6e9
on 1/12/2009 to correctly handle "loose on time"
LSN filtering functionality, but is now unused.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This L1/L2 optimization has an incredible +4.7% speedup
in perft test where this function is the most time consumer.
Verified a speed up also in normal bench, although smaller.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
UCI protocol uses "true" and "false" for check and button types,
so store that values instead of "1" and "0", this simplifies a
bit the code.
Also a bit strictier option's type checking in debug mode.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This patch greatly cleanups generation of pawn moves but
we change the order in which moves are generated so there is
a change in functionality, but not in perft.
The only real functionality change is that now when type == CHECK
we generate knight underpromotion captures only if give check and
not always as before.
Perft is 2% faster and fully verified.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now stockfish bench' defaults to
stockfish bench 128 1 12 default depth
that is the most used line (at least by me)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Let to sleep even split point master, it will be waken
up by its slaves when they return from the search.
This time let it be enabled by an UCI option, so
people is free to test it on their Hyper Thread box.
Option is disabled by default.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Search at fixed depth with one thread must be
reproducible so remove randomess from time().
Also better license description.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
I finally got SF to compile under MinGW (after adding pthread libraries)
and here are the fixed warnings.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And also store the node counter in Position and not in Thread.
This will allow to properly count nodes also in sub trees with
SMP active.
This requires a surprisingly high number of changes
in a lot of places to make it work properly.
No functional change but node count changed for obvious reasons.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This was subtle and google was my friend.
The leak was in _dl_allocate_tls called by pthread_create() and
is due to the fact that threads are created in joinable state so that
once terminated are not freed. To make the thread to release
its resources upon termination we should set them in detached state.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix warning: "Source and destination overlap in memcpy"
This happens when we call multiple time do_move() with the
same state, for instance when we don't need to undo the move.
This is what valgrind docs say:
You don't want the two blocks to overlap because one of them could
get partially overwritten by the copying.
You might think that Memcheck is being overly pedantic reporting this
in the case where 'dst' is less than 'src'. For example, the obvious way
to implement memcpy() is by copying from the first byte to the last.
However, the optimisation guides of some architectures recommend copying
from the last byte down to the first. Also, some implementations of
memcpy() zero 'dst' before copying, because zeroing the destination's
cache line(s) can improve performance.
In addition, for many of these functions, the POSIX standards have wording
along the lines "If copying takes place between objects that overlap,
the behavior is undefined." Hence overlapping copies violate the standard.
The moral of the story is: if you want to write truly portable code, don't
make any assumptions about the language implementation.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems we have a speed regression under Linux, anyhow
commit and revert to leave some documentation in case we
want to try again in the future.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Let to sleep even split point master, it will be waken up
by its slaves when they return from the search.
With this patch we get maximum HT speedup
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It has more sense to treat the two evaluation metrics
in the same way.
As a side effect now we use the correct eval margin when
pruning in a SplitPoint node.
No functional change in single thread.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix the movcount updating bug and let search() to completely
subsititute sp_search().
No functional change even with fakes split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
There is a bug in the conversion that is triggered when testing
with faked split and that I missed somehow :-(
To allow proper testing on cluster restore old sp_search()
until I don't fiugre up what's happened.
Restored to be functional equivalent to old behaviour both in
single thread and in faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When entering and exiting from think() we don't need any special
wake up / sleeping code because we want available threads to keep
sleeping.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This simple patch has devastating consequences ;-)
Now an available thread goes to sleep and is waked up after
being allocated.
This patch allows Stockfish to dramatically increase performances
on HyperThreading systems.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
They are fast and also have the same semantic of Linux ones.
This allow to simplify the code and especially to use
SleepConditionVariableSRW() to wait on a condition releaseing the lock,
this has the same semantic as pthread_cond_wait().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is a prerequisite for future work and anyhow removes
a state flag, so it is good anyhow.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is redundant and complicates the already complicated
SMP code for no reason.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We already do this for locks. Also rename SitIdleEvent
in WaitCond to be uniform with Lunix naming.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is the native way done in Windows and we will use it
for future work, so change Linux to do the same.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Plus some other icc warnings popped up with new and strictier
compile options.
No functional and speed change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It has more sense to treat the two evaluation metrics
in the same way.
As a side effect now we use the correct eval margin when
pruning in a SplitPoint node.
No functional change in single thread.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Rewrite sp_search() to have same signature of search()
This is the first prerequistite step toward unification.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Actually it is an error to update back moveCount value after split()
because it is used in update_history() to access movesSearched[]
array. But becasue this vector is not updated in the split point
we end up with an access of stale data.
Bug has been hidden til now because we 'forgot' to update
moveCount before returning from split().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Mostly suggested by Justin (UncombedCoconut), the 0ULL -> 0 conversion
is mine.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Language guarantees that c'tor is called, but without any c'tor
it happens to work by accident because OS zeroes out the freshly
allocated pages. The problem is that if I deallocate and allocate
again, the second time pages are no more newly come by the OS and
so could contain stale info.
A practical case could be if we change TT size or numbers of
threads on the fly while already running.
Bug spotted by Justin Blanchard.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix release to workaround chess960 on some GUIs
Signature is:
stockfish bench 128 1 12 default depth
Node counts: 10914593
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Get rid of macros and use templates instead,
this is safer and allows us fix the warning:
ISO C++ forbids braced-groups within expressions
That broke compilation with -pedantic flag under
gcc and POPCNT enabled.
No functional and no performance change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This patch from Joona greatly reduces move count pruning,
below is the old and new move count limits starting from
ONE_PLY with half-play increment:
Old: 4,5,5,5, 7, 7,11,11,11,19,19,19,35,35
New: 4,5,7,9,12,15,19,23,28,33,39,45,52,59
Surprisingly results are even a bit better at a quite
fast time control.
After 5260 games at 30"+0.1
Mod - Orig: 864 - 806 - 3590 ELO +3 (+- 3.8)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems totally unuseful because killers are not
used to order the moves in qsearch. Although there
is some functionality change, probably just a small
side effect.
After 5656 games on rc
Mod vs Orig: 1007 - 980 - 3669 ELO +1 (+- 3.7)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So there is no need to explicitly check for king moves
when detecting prunable evasions.
Perhaps teoretically a very bit slower (I didn't test),
but it is more clear now what evasions we consider prunable.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Greatly cleanup SEE code and now it is also a bit
faster on gcc, about +0.6%.
Thanks to Mike Whiteley new SEE code that gave me
fresh ideas on how to cleanup this old stuff.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A code semplification that could even be a slight increase,
anyhow is a reducing pruning patch, so it is good even
at equal strenght.
After 6342 games
Mod - Orig: 1040 - 974 - 4328 ELO +3 (+- 3.5)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Were removed when merged from Glaurung 2.2, but without
any test.
Note that weight has been increased from original 2 to 4 and
has been also fixed a bug where in the original version were
considered also diagonal sqaures for the rook, that are
contact squares but not checks.
After 4449 games at 30"+0.1
Mod - Orig: 717 - 649 - 3083 ELO +5 (+- 4.1)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use the tail of moves[] array to store bad captures.
No functional change but some move reorder. Verified with old perft.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And also other check bonuses.
After 4272 games on russian cluster at 30"+0.1
Mod - Orig: 711 - 612 - 2949 ELO +8 (+- 4.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
More then 100 lines of almost useless evaluations. Prefer
code semplification to a very small and dubious advantage.
After 7457 games on russian cluster:
Mod - Orig: 1285 - 1334 - 4838 ELO -2 (+- 3.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And rename in nodes now that we have only one.
After the beta-cut off counters removing we can
get rid also of this one.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
For now keep FutilityMarginsMatrix[] unchanged, in
future we are going to reduce to compensate for extra
margin.
At this moment it is enough we don't have regressions.
After 9694 games on russian cluster
Mod - Orig 1608 - 1578 - 6508 ELO +1 (+- 2.8)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of one comparison in while() condition use two,
the first to check if the piece is exsistant and the second
to loop across pieces of that type.
This should help branch prediction in cases we have only
one piece of the same type, for instance for queens, the
first branch is always true and the second is almost always
false.
Increased speed of 0.3-0.5 % on Gcc pgo compiles.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently are used by evaluation itself and the
whole EvalInfo will be removed from global visibility
by next patch, so no reason to use them.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It will be more clear when we will go to add stuff
apart from king danger itself.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
First accumulate the bonus for each pawn, then call the
not very fast apply_weight().
Should be no functional change apart from rounding issues.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Set manually to zero the few fields that are
optionally populated and that's enough.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Avoid one address lookup in a very critical time path.
Unified also outpost bonus tables for knights and bishops.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Another 100 lines of dubious and ad-hoc code.
After 7644 games on russian cluster:
Mod - Orig 1285 - 1249 - 5110 ELO +1 (+- 3.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We don't need that !
We can infere from starting fen string if we are in
a Chess960 game or not. And note that this is a per-position
property, not an application wide one.
A nice trick is to use a custom manipulator (that is an
enum actually) to keep using the handy operator<<() on the
move when sending to std::cout, yes, I have indulged a
bit here ;-)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Plus a bunch of other minor optimizations.
With this power pack we have an increase
of a whopping 1.4% :-)
...and it took 3 good hours of profiling + hacking to get it out !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
One hundred lines of code should be compensated by an
important ELO increase, otherwise are candidate for removal...
...and is not the case. We are well within error margin, so
remove the code even if we lose a couple of elo points, but
semplification is huge.
After 6494 games on russian cluster
Orig vs Mod 1145 - 1107 - 4242 (-2 ELO)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After testing on our russian cluster: +3 elo after 4200 games
So keep it becuase it allows a good semplification.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Where they belong.
Note that array PieceValueMidgame[] and PieceValueEndgame[]
are now declared extern in the header and moved in piece.cpp
so to avoid allocate the array each time the header is
included !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
To avoid nasty bugs due to silently overriding of
common operator we enable the templates on a type
by type base using partial template specialization.
No functional change, zero overhead at runtime.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Note that in value we leave two specialized functions
to allow adding an integer, we don't want to add this
as a template becasue we want to control implicit
conversions to integer of an enum.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is tricky because there are some special
binary fnctions with SquareDelta that we should
leave as they are.
Also note that we needed to add Unary minus template
to fix a comile error in SERIALIZE_MOVES_D macro that was
triggered because now we don't allow conversion to int.
No fuctional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Doing the conversion the compiler is now able to
spot two possible ambiguity calls that now we can
easily fix.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When depth < DEPTH_ZERO we store with the same depth all
the positions, use -OnePly instead of -1 for consistency
with depth arithmetic.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
There is no reason to use a variable for this.
Also remove unused DEPTH_ZERO and DEPTH_MAX.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Regression test found the patches to be harmless,
so revert to keep code simpler.
Test1 at 20+0.1: (2500 - 3000) +0 ELO
Test2 at 1+0: (~1000) +2 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
There is a functional change because we now skip
more moves and because do_move() / undo_move() is
well known to be not reversible we end up with a
change in node count, although there is actually
no change but a bit speed up.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
To be uniform across the sources. As a nice side effect
I quickly spotted a couple of needed renames:
captured_piece() -> captured_piece_type()
st->capture -> st->capturedType
Proposed by Ralph and done with QtCreator
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In root_search() we can compute depth at the beginning
once and for all.
Spotted by Ralph Stoesser.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We don't need to generate captures and non
captures in a separate step. This gives another
7% push to perft speed.
yes, I know, it is totally useless :-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We can now set member data as private because is no more
directly accessed.
Should be more clear now.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Move OptimumSearchTime, MaximumSearchTime and
ExtraSearchTime in TimeManager.
Note that we remove an useless initialization to 0 because
these variables are used only with time management.
Also introduce and use TimeManager::available_time()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Firt step in unifying all time management under
a single umbrella. Just introduced the class without
even member data.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After razoring, IID, null verification and singular
extension searches we have could have a dirty ss->bestMove,
restore to MOVE_NONE before to enter moves loop.
This should avoid to store in TT a stale move when
we fail low.
Tested together with previous patch that is the
one that gives ELO.
After 1152 games at 1+0 on my QUAD
Mod vs Orig +233 =716 -203 (+9 ELO)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If singular extension search was succesful in the past then
skip another the SE search and extend of one ply.
Another way to mitigate the cost of SE at the price of
some more spurious extension, but on 90% of cases info
is correct.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Renamed in OptimumSearchTime and MaximumSearchTime,
should be more clear now.
Suggested by Joona.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
I created three different systems, tested them all separately and
attached one did best:
1/40: Orig - Mod: 841 - 850 (+2 elo)
1+1 : Orig - Mod: 474 - 498 (+9 elo)
1+0 : Orig - Mod: 455 - 495 (+15 elo)
Because such testing system is not statistically reliable, I made a
confirmation test:
1/40: Orig - Mod: 502 - 543 (+14 elo)
1+1: Orig - Mod: 447 - 489 (+16 elo)
1+0: Orig - Mod: 641 - 656 (+4 elo)
All tests show positive score :-)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of ss->currentMove. It is more consistent and
clear to understand.
Remark by Ralph Stoesser.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
To compensate for the extra work skip singular
searches deemed to fail because excluded node
failed high already in the past.
After 1200 games at 1+0
Mod vs Orig +387 =1274 -339 (+8 ELO)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The one in evaluate_passed_pawns() is just a micro
optimization, the other in evaluate_unstoppable_pawns()
is indeed a fix, although almost unmeasurable in real
games.
Bugs report and fixes by Marek Kwiatkowski
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Broken by recent patch. Also better document what's
happening there.
Verified to restore original behaviour.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Square and piece colors are two different things,
so use different types to avoid misunderstandings.
Suggested by Tord.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Less invasive then previous patches, but still a good
enhancement.
Also some indulge on STL algorithms :-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Complete rewrite the function and extend compatibility
also to X-FEN notation for Chess960.
We are now able to read standard FEN, Shredder-FEN and X-FEN.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After 'Randomness' is retired, this is no longer necessary.
NOTE: Possibly some extra care is needed when tuning branch is synced
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Using multiple threads and good opening book is
much better and more reliable source of randomness than
spoiling psqt-tables
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Let be explicit about what this functions do, and
we save some code lines too.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After we set ss->threatMove we could go under a IID step that
resets SearchStack ss and so also ss->threatMove.
When later we use that field in futility pruning we have this
set to MOVE_NONE !
The fix is to use a local variable and add threatMove to SplitPoint
to pass this move to slaves.
Spotted by Ralph Stoesser, fix suggested by Richard Vida.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Improvement is easily in error bar and there is
some added complexity making future changes more
difficult.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Because not all backward pawns are the same ;-) if the
blocking enemy pawn is near then our pawn is more backward
than another whose enemy pawn is far away so that can advance
for some sqaures.
After 2925 games at 30"+0 on my QUAD
Mod vs Orig +602 =1745 -578 +3 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Update outdated and even misleading documentation.
Also check #include-directives
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
These functions have little to do with TranspositionTable
class and more with the search and in particular with the PV
handling. So move them where they belong.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So to maximize the possibility to avoid to recalculate it
in the future. A small speed-up of 0.8%
Idea by Ralph Stoesser.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The seocond check is no more needed now and
anyhow is wrong to overwrite a TT entry if
present.
Spotted by Ralph Stoesser.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
KILLER_MAX in search.h is quite pointless, because
we already hardcode this to 2 in MovePicker anyway.
By hard-coding this to 2 we can keep code simpler.
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is more clear and also more correct because we
consider enemy pawns only in fornt of us and not just
on our file.
Very small functional change, almost not measurable, but
keep the patch for documenting purposes.
Spotted by Marek Kwiatkowski.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Almost no change so commit because is a pruning
reduction patch.
After 1088 games at 1'+0 with QUAD
Mod vs Orig +178 =727 -183 (-2 ELO)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We don't need to pass side_to_move because we can get
it directly from the position object.
Note that in benchmark we always used to pass '0' and
it was a bug, but with no effect because was used only
in time[] and increment[], set always to 0 for both
colors.
Also additional small cleanup while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Considering only VALUE_TYPE_EXACT nodes is too
restrictive and has a number of side-effects, most
notably the truncation of PV line after a fail high
at root.
Note that in this way we are no more guaranteed that
PV line is built up with PV nodes only, because
it could happen that a side search overwrites with a
cut-off move a PV node and this cut-off move ends up
in PV.
Change should be almost not measurable, perhaps with
ponder on we could have some beneficial effect.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently starting from depth 12*OnePly on we have a verification
search deeper then the null search.
Note that, although reduction is R we start from one ply less then
null search, so actually we reach a depth that is OnePly shallower
then null search.
After 1130 games at 1'+0 on QUAD
Mod vs Orig +202 =756 -172 +9 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After the previous patch, it's impossible to build
anything else than x86 32-bit binary!
So revert.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Tested with Orig set at f5ef5632f so to evaluate
direct gain against 1.8
After 3239 games at 10"+0.1
Mod vs Orig +701 =1906 -632 +7 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Unfortunatly the source of this issue is not in the
different handling of log(0) illegal value.
No functional change on MSVC.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It happens that when d == 0 we calculate:
log(double(0 * 0) / 2)
Unfortunately, log(0) is "illegal" and can generate either a
floating point exception or return a nonsense "huge" value
depending on the platform.
This fixs in the proper way the GCC/ICC rounding difference,
bug was from our side, not in the intel compiler.
Also fixed some few other warnings.
Bug spotted by Richard Lloyd.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also renamed history access value in something more
in line with the meaning.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems there is absolutely no difference in using gains.
After 7025 games at 5"+0
Mod vs Orig +1903 =3236 -1886 (+1 ELO)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This time with a new algorithm by Joona.
It works basically like this:
repeat
{
1) pick 8000 random positions from qsearch
2) "go depth 8" to get the true evaluation.
3) "eval" to get the stand pat score
4) Adjusting parameters one by one to minimize deltasum between
true evaluation and stand pat scores.
}
* Good news: method seems to converge
* Bad news: Point where it converges is not optimum.
So it's more or less trial and error... sometimes works, sometimes
doesn't. It can give you the right direction, but if you let it run
too long, it fails. Far from scientific ;)
After 14800 games with 5s/game
Orig - Mod: 3318 - 3570 - 7626 (+6 elo)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When first condition is met then second one is
always true.
Spotted by Ralph Stoesser.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This should allow to skip overwritten nodes because
only in PV we store in TT with VALUE_TYPE_EXACT flag.
Test result for the whole series is:
After 3627 games at 5"
Mod vs Orig +1037 =1605 -985 +5 ELO
After 1311 games at 1'+0"
Mod vs Orig +234 =850 -227 +2 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Extract PV info from TT instead of using
a set of arrays. This is almost equivalent
except for cases when TT is full and the PV entry
is overwritten, but this is very rare.
(Almost) No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Due to rounding errors in apply_weight() where we divide
by 0x100 it is not possible to keep some functionality.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A pawn is unstoppable also if enemy king can reach it
but path to queening is protected.
Original idea by Ralph Stoesser fixed by me.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Many killers moves, around 40%, are not legal, so
skip earlier in this case.
Some Movepicker c'tor cleanup while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This code is platform specific and has nothing to
do with TT class, so move to misc.cpp
This patch is a prerequisite to use extend prefetch use
also to other hash tables apart from Transposition Table.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Search ply and game ply are rwo different things !
Revert bogus commit.
No functional change on bench, but it changes in real games
when engine sends all the moves up to current one.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If we are there it means we already had that info stored in TT,
so we don't need to overwrite with the same content !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In statement:
*tte = TTEntry(posKey32, v, t, d, m, generation, statV, kingD);
We first create a TTEntry, then we copy the temporary entry to
its final destination in *tte then we discard the TTEntry.
Instead of this assign the fields directly to the destination TTEntry.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is more clear and should be a bit faster too.
Reverted also previous optimization patch because
seems do not increase actual speed.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Almost no change, but it is in sync with what we do in search
and in any case the ELO difference is very small (because the
events when the intermediate research triggers are very rare),
too small to be measured, we just verify we don't have any
unexpected regressions.
After 802 games at 1+0 full QUAD
Mod vs Orig +114 =581 -107 +3 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If we have pruned one capture due to its final value
we can prune also following ones because captures are
MVV ordered.
Also avoid a compare when not in PV because in that
case is always false.
No functional change.
Get it from the position instead.
A good semplification of function calling and a speedup too.
No functional change also with faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is the best place because when we split we do a
copy of the position and also threadID, once set in a
given position, never changes anymore.
Forbid use of Position's default and copy c'tor to avoid
nasty bugs in case a position is created without explicitly
setting the threadID.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Do it once at the beginning becuase they are always reset
after use in the calling place where are set.
No functional change also with faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also renamed allowNullmove in skipNullMove to reverse
the logic so that the field is initialized to 0 (false)
instead of 1 (true).
No functional change also with faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use log() instead because we are not in speed
critical paths.
Also a bit of renaming and code shuffle while there.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Has been remained the same from ages also with the FIXME.
Retire for now and rearrange the conditions order for
maximum performance.
Also a small touch at null zugzwang verification.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is more up to the point. Also small speedup
due to checking for threat move before calling
the function. This saves more then 90% of function calls.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In 44% of cases we call search() just to call
qsearch() one moment later, avoid this double dispatch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And avoid a redundant one passed as argument in
search calls.
Also renamed gamePly in ply to better clarify this
is used as search ply and is set to zero at the
beginning of the search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In RootMoveList c'tor we call qsearch() with
ply == 1 but SearchStack at 0.
We never noticed before because in qsearch we don't access
previous's ply SearchStack, otherwise we would have got
a nice crash ;-)
This bug is a fall down of previous patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use a pointer to current SearchStack to avoid ss[ply]
address calculation.
Gives 1% speedup on Intel compiler
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And remove from main do_move() flow. Just a small speedup
because we avoid two branches in the common case.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In case tte->depth() is far lower the current depth
and we are in a PV node.
Almost 45% of researches give a different ttMove !
After 999 games at 1+0
Mod vs Orig +174 =694 -131 +15 ELO !!!!!!!
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Do not search immediately at full depth, but try a second
chance at lower depth. This is a feature that should scale
well because become important at high depths where we have
big reductions and also big savings in avoiding a costly
full depth search.
After 942 games at 1+0
Mod vs Orig +158 =645 -139 +7 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The index at 0 was reserved for no-pieces
information. But we don't need that.
This is a prerequisite for next patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
They are both 64 bits unsigned integer, but it
is correct to use the proper type.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After 999 games at 1+0
Mod vs Orig +148 =712 -139 +3 ELO
The added complexity doesn't seems to pay off and could
even scale worst with longer TC. So revert.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The tested square comes from a bitboard anded with
pos.pieces_of_color(Us), so assert is useless.
Another nitpick report by Marek Kwiatkowski ;-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
One of the most nitpicking patches I have ever seen.
Of course almost no functional change, but added just
becasue we are very pedantic ;-)
Spotted by Marek Kwiatkowski
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It was erroneusly reversed. Bug from Glaurung times.
Probably a full re-tuning is needed anyhow.
Spotted and fixed by Ralph Stoesser.
After 999 games almost no change, but modified anyway
for documentation reasons.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Increase threats score according to the number of
threats and to the side to move.
Constants have been balanced after ~34k iterations.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It does not seem to increase anything even with a QUAD,
so revert.
After 1000 games with a QUAD
Mod - Orig: 500 - 497 (+1 elo)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When compiling with MSVC we don't use the Makefile
so tweak a bit the Makefile to allow to let prefetch
in by default so that it works under Windows.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
No gain in the worst case of 2 threads, but also no
loss and good potential for QUAD or OCTAL machines.
After 922 games at 1+0 with 2 threads
Mod vs Orig +143 =533 -143 +0 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We already tested few lines before with:
assert(pos.pawn_is_passed(Us, s));
Spotted by Marek Kwiatkowski.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Does not help and it slows downs a bit because it
is not cheap to get the possible discovered checks
out of a position.
After 997 games at 1+0
Mod vs orig +153 =692 -152 +0 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
There is no reason for that since tr cannot become negative.
Spotted by Ralph Stoesser.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Final values for threath tuning (after ~30k iterations)
Verified to be equivalent with tuning branch.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is a more standard naming (see chessprogramming wiki)
and is more stick to what table is and not what is used for.
Code in pawns.cpp is a bit more readable now, at least for me ;-)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Avoid a double bitcount in test for candidate passed
pawn when we don't have any supporting pawn.
Also use outpost_mask() instead of build it up on
the fly.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Pass the color for which the square is to be
considered weak, not the opposite.
It is more natural and intuitive in this way.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Function split() doesn't need to return a value, also
remove useless 'master' field.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is redundant with splitPoint->slaves[].
Also move slaves[MAX_THREADS] among the shared data in
SplitPoint definition as it should have been already.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Small twekas to make the two searches as similar as
possible.
Also removed an useless setting of mateKiller in sp_search()
No functional change (tested with FakeSplit)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We don't need to comment/uncomment code, just
set FakeSplit bool to true to enable faked split.
Also reintroduced some asserts and cleaned up a bit.
Tested that with FakeSplit = true we have reproducible
finger printing even in SMP.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also introduce a new rule:
In sp_search() always must hold: sp->alpha < sp->beta
Should fix some rear but very nasty races
To keep everything in sync, search() is also modified to
obey this rule. Because this affects only PV-nodes, should
have zero meaning to speed.
No functional change in fake mode
Regression test after 854 games
Mod vs Orig 433 - 421, no crashes.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It was broken on Windows 64bit with MSVC and possibly
on other platforms, so revert to old proven one.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Remove a lot of complex, obscure and useless code.
After 999 games at 1+0
Mod vs Orig +162 =673 -164 -1 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We don't need to evaluate the position if it
is already cached in TT. We already do this
in non-PV case.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is what actually is.
A standard naming convention suggests to name a variable
with someting resembling _what_ the variable is and not
_how_ the variable is used. This normally results
in easier to read code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A bigger "safety" value is actually a bigger
threat for the king, so it is a bigger "danger"
With this renaming "Cowardice" and "Aggressiveness"
UCI parameters become easier to understand.
It is also easier to understand why the once "safety"
value (that is a "danger") is subtracted from evaluation
instead of being added.
No functional change.
Use a Weights[] array instead of named variables to
store evaluation weights.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
More aggressive LMR reductions.
Tested at different time controls:
- Tested with 1CPU 1+0, after 3000 games, result was +12 ELO
- Tested this with 4CPU 1+0 and got sth around 5-10 ELO increase
- Last one at long time control,after ~1000 games with 10+0 result is:
Orig - Mod: 491 - 520 (+10 elo)
A testing marathon by Joona for this important change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Master thread returns from idle_loop() when sp->cpus == 0,
but cpus is decremented by slave threads under sp->lock,
so it could happen that we return in split(), where we release
the split point, with sp->lock still held.
This patch guarantees that sp->lock is released when returning
to split().
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The idea here is that if we cut-off after a stand pat the
already exsisting TT entry was not usable with current
beta, so overwrite anyway.
After 999 games at 1+0
Mod vs Orig +173 =665 -161 + 4 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Almost no change and simplifies a bit the code.
After 961 games at 1+0
Mod vs Orig +156 =650 -146 +4 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Re-save the same TT entry if value is usable and allow
us to cut-off, it means that entry is valuable and
we want to keep it fresh updating the 'generation'
parameter up to the current value.
Patch suggested by J. Wesley Cleveland and better
clarified by Miguel A. Ballicora.
After 999 games at 1+0 64MB hash size
Mod vs Orig +167 =677 -155 +4 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In this case we avoid to name the 'black' version of the
endgame function but use a vector indexed by color instead.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Because exit_threads() references the global object TM, we
need to call the function when still inside main(), otherwise,
due to undefined global object initialization and destruction
we could end up with referencing an already destroyed object.
Actually this should not happen because Application singleton
is initialized _only_ after all the other globals due to how
Application::initialize() is defined, but this is very tricky
C++ and not easy to follow, even for me ;-)
Also rearranged a bit main() code flow.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Moved evaluation of unstoppable pawns out of
evauation of passed pawns because event frequency is
much lower. Added evaluate_unstoppable_pawns() that
is called very seldom and contains all the unstoppable
pawn logic.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Should be a very minor change, but there is a small
functional change because futility_margin() is used in more
places then in the pruning formula.
After 999 games at 1+0
Mod vs Orig +167 =678 -154 +5 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also fix dimension of UnpairedPawnsTable[] to accomodate the
case in which we have 8 unpaired pawns, i.e. only one side has
pawns, the other side has no pawns.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The idea is to reduce the score if we have many
pawns opposing an enemy pawn so that the draw
possibility increases.
Just introduced the logic, but no functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A pawn is candidate to be passed if doesn't have enemy pawns
in just front of him, not also behind !
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Absolutely no useful at all, just code obfuscation so
use real definition instead.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It will be used to lookup squares in front of
a given square. Same concept of PassedPawnMask[]
and OutpostMask[].
Also small tweaks in bitboard.h
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now with:
stockfish bench 128 1 5 default perft
it is possible to get perft 5 results of each position and
the first 3 positions correspond to the well known test
position in:
http://chessprogramming.wikispaces.com/Perft+Results
This allow to quickly check for perft consistency running
the 'bench' command.
No functional change but signature has changed because
bench default positions 2 and 3 have changed.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Revert all the patches that introduced the change and
more or less fixed the zugzwang issue.
There is a gain against last current version and we
can remove a lot of code.
After 979 games at 1+0 on my QUAD
Mod vs Orig +152 =688 -139 +5 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Real search is considered of higher quality then null
search one.
This allows to fix the zugzwang issue with a minimal
impact on ELO.
Zugzwang verified on position:
8/7P/8/8/K2b4/p7/1k6/1B6 b - -
After 999 games at 1+0 on my QUAD
Mod vs Orig(94bb196) +168 =657 -174 -2 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Is a boolean option that when set allows Stockfish
to select the best book move across the possible ones.
Feature requested by Salvo Spitaleri.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Avoid incorrect mate scores in positions like
BK5/1R4b1/2k1Np2/3p3b/2p3pq/p1rB4/n2n1p2/8 w - -
Thanks for Jouni Uski for reporting the problem
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is the world's fussiest compiler with +w1
Warnings reported by Richard Lloyd.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add an UCI option "Zugzwang detection" OFF by default that
enables correct detection of zugzwang.
This is just to let 1.7.1 be 100% compatible with 1.7 and
should be removed after release.
Verified 100% functional equivalent to 1.7
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It fails in test position:
8/7P/8/8/K2b4/p7/1k6/1B6 b - -
Not clear why but we revert because it fixes the issue.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In this case use a normal VALUE_TYPE_LOWER TT type instead of
VALUE_TYPE_NS_LO. This allow us to TT cut-off in a bit more nodes.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This patch fixes an issue with zugzwang well explained by Tord:
"Assume that a zugzwang position occurs at iteration N,
at a search depth d, with d < 6*OnePly. The null move search
fails high, and no verification search is done, because the
depth is too small. The position gets stored in the transposition
table with a good score and a depth of d.
Now, consider what happens when the same position occurs at iteration
N+1, this time with a depth of d+OnePly (i.e. one ply deeper than at
the previous iteration). Once again, the null move search fails
high. The point is that the verification search will also fail high,
because of an instant transposition table cutoff caused by the value
stored in the TT during the previous iteration."
With this patch we simply do not allow TT cutoffs at the root node
of a null move verification search if the TT value was found by a
null search.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Add VALUE_TYPE_NS_LO to enum ValueType and use it when
saving in TT a value from a null search.
Currently no action is performed, the next patch will enable
the new type.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Reported warning is:
warning #2514-D: pointless comparison of unsigned
integer with a negative constant
Spotted by Richard Lloyd.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Under gcc we have:
warning: dereferencing type-punned pointer will break
strict-aliasing rules
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use full depth, not reduced one. This allows
to avoid to do a null search when in the same
position and at the same or bigger depth the
null search failed high.
A very small increase, if any.
After 963 games at 1+0
Mod vs Orig: +158 =657 -147 +4 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In this form it is even more evident we have some
issue there to be fixed sooner then later....
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After previous patch we don't need any more the call parameters.
This fixes a couple of warnings under MSVC.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After 500 games at 5+0 on my QUAD (3 days) there
is no difference with old version, so probably it
is a feature that doesn't scale with search depth.
So revert for now, perhaps we should readd under a
different form.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
MSVC complains about an implicit conversion from double to int.
Also small comments tweaks.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In the beginning use milder reduction and at the end be
more aggressive.
After 1500 games on Joona's QUAD
Mod - Orig: 791 - 720 +16 elo
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Causes very small functional change which is not observable with
our usual set of test positions.
However change is observable fx. with following position:
4k3/3r4/5Q2/6K1/8/8/8/8 w - - 0 1
go depth 24
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If null search fails high return null value instead of beta.
With TT hash there may be a small advantage for fail-soft since
storing slightly better bounds may cause slightly more hash hits.
After 990 games at 1+0
Mod vs Orig +171 =665 -154 +6 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Array castleRightsMask[] is not static because it can
be different for different positions, so let it be
a Position member data. This allows to remove tricky
hacks to take in account that although it was defined
static it could change.
Theoretically now copying a position is a bit slower because
we need to copy also an array of 64 integers, but because in
split() we don't copy the position anymore, but just keep the
pointer, the added burden is not mesurable even in MP case.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also don't use __cpuid() intrinsic for Intel under
Linux because gives wrong results when detecting HT,
use the gcc version instead. Finally clean up the code.
Error was due to changed __cpuid() signature for
gcc compiler.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This will allow to use the function also for other
purposes then detecting POPCNT.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It will be used by future patches and also rearranges some
half cooked code that mistakenly ended up in master in the
past.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently, in case of fail high/low we research with
a window increased by 2*AspirationDelta at first
attempt, this patch instead makes the research be
done with an increase of just AspirationDelta size,
in case of a consecutive fail we will widen to
2*AspirationDelta and so on.
After Joona's test:
Orig - Mod: 850 - 890
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
One for failing highs and one for failing lows, this
should reduce average window size in case of positions
that fail first high and then low (or the contrary).
After ~2000 games on Joona's quad we have:
Mod - Orig: 1012- 975 (+6 elo)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead to leave uninitialized or scattered in the code
as is the case for ExtraSearchTime.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently we use original sorting after a fail low to
research at wider window. This patch instead sorts the
moves according to the last available move's scores.
Strangely no functional change, but should be.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Changed FutilityMarginsMatrix dimensions to be a power of two
so that compiler can produce a faster accessing code.
Introduced print_pv_info() to remove some redundant code in
root_search()
Remaining stuff is triviality and documentation tweaks.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Under Windows we use CreateThread() to setup threads and
we pass a pointer to a variable that receives the thread
identifier, but this parameter is optional and we don't
use it, so remove it.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It happens that NULL is 0, but the conventional meaning is of
a zero pointer, so repleace with an explicit 0 integer value.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Consider sligtly negative captures as good if at low
depth and far from beta.
After 999 games at 1+0
Mod vs Orig +169 =694 -136 +11 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It raises an assert under Windows, it is not clear why but it
happens that idle_loop() is called with incorrect threadID and
the assert triggered is:
assert(threadID >= 0 && threadID < MAX_THREADS);
So revert the patch for now, but we should understand why it
fails.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We can't do it with full guarantee anyway because
there is always a possible race between the setting of
state to THREAD_SLEEPING and actual sleeping.
So just remove the not perfect code to avoid misunderstandings.
This reflects what we have done in wake_sleeping_threads() in
the previous patch.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently there is no guarantee that threads are sleeping
when calling wake_sleeping_threads() because put_threads_to_sleep()
returns without waiting for threads to actually sleep.
Assert can be easily triggered calling put_threads_to_sleep() and
wake_sleeping_threads() in a tight loop.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This option likely has very low meaning for playing strength and style,
so I see no need to keep this configurable
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
search() is used as a "leading star" and other routines
are modified according to it.
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Was broken and fixing would be too messy.
Now this option is only activated in single thread mode
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Just to avoid misunderstandings.
True staticValue is available through search stack
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Bug spotted by Jouni Uski and fix suggested by Pablo Vazquez
Also add note that we are not always handling fifty move rule correctly
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
I cannot see connection between the two.
Also add one FIXME for illogical behaviour
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
I don't know if enumerating sections is a good idea,
but for me code is more readable this way
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
I cannot see any reason to do this. Even this is not enough to fix
theoretical race case on Windows which doesn't seem to cause any
problems in practice anyhow
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Resurrect extra check for sleeping in POSIX code.
This necessary to prevent ugly races between
thread_broadcast and thread_cond_wait.
After thread has woken up, it marks itself as available.
Another thread must not do this, because of possible race.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So we can use a const value instead of a pointer in
split().
Also pass NULL instead of a faked address of alpha in
case split is called from a non-PV node.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Intrinsic __popcnt64() returns an unsigned __int64, cast
to an integer and silence the warning.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Joona says that sp_update_pv() does not pass the split point
boundaries, so there is no risk to corrupt data from another
split point. Also the race on thread_should_stop() is harmless
because of this.
So revert the patch and come back to single lock.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Joona says:
1. We should not be afraid of "AllThreadsShouldExit" flag.
Because when this is set to true we _must_not_ be searching (= All
splits must have been undone).
And if we are not searching it's impossible that some other thread
could give us work to do. So setting state to THREAD_AVAILABLE
doesn't do any harm. If you want to add check for this, you could do
it like this:
if (threads[threadID].state == THREAD_WORKISWAITING)
{
+ assert(!AllThreadsShouldExit)
threads[threadID].state = THREAD_SEARCHING;
2a. If waitSp->cpus == 0, setting state to THREAD_AVAILABLE makes
no harm either, because helpful master concept dictates that _only_
our own slave can book us. If we don't have any slaves, noone has the
right to book us.
2b. If point (2a) is not correct then your extra check only adds extra race:
In smp code checking for waitSp->cpus > 0 is not enough. It's possible that
our slave immediately exits and another thread
books us as a slave when our state is still
THREAD_AVAILABLE. So instead of adding extra level of security we have
just introduced extra race.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When we found a cut-off then lock all the split point chain,
not only current one to avoid races in case two threads running
on different split points where one is ancestor then the other,
find a beta cut-off at the same time, in this case we want only
one to call sp_update_pv().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is a per split-point request, not per-thread. When we find
a beta cut-off in current thread's split point or in or in some
ancestor of the current split point then threads should stop
immediately the search and return to idle_loop().
The check is done by thread_should_stop() that now looks only
at split point's chain.
No functional change and a good semplification.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is easier to follow and also reduces the points
where state changes to mainly idle_loop() and split().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is because when we are below 4 * OnePly, the null move
will directly jump to qsearch and if we are below beta,
our opponent is above beta and will get immediate
stand pat cut off.
So basically this patch is just optimizing away useless
evaluation calls. dbg_hit_on() runs show that this heuristic
is correct >99% of cases. Transposition table probably causes
some inaccurary?
After 1148 games on QUAD
mod-orig: 583 - 565 +5 elo
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In this case is dangerous because in split() we reset the flag to
false, but if it was set due to a cut-off higher in the tree we
completely miss that and go on with the full search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of other flags this is not a state flag, i.e. does
not defines a state for the thread, but a request because
after we raise 'stopRequest' flag the corresponding thread is
not stopped, but continues to run for a while until it returns
from sp_search() in idle_loop.
It is important the name reflects this.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Among them 'stop' and 'printCurrentLineRequest' could have
random value, so reset to a known state before to leave the
search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is the first nice effect of previous patch !
Because thread_should_stop() should be declared 'const' we
need to remove the setting of 'stop' flag to true that
turns out to be a bug because thread_should_stop() is called
outside from lock protection while 'stop' flag is a volatile
shared variable so cannot be changed when not in lock.
Note that this bugs fires ONLY when we use more then 2 threads,
so commonly only in a QUAD or OCTAL machine.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Main aim of this patch is to consolidate all the thread related stuff
behind a single class interface so to avoid messing with global flags
and having thread code scattered among non-thread related stuff.
Another advantage is that now access to thread's variables is
more controlled, in particular we can differentiate between
read and write accesses by the mean of different interfaces, it
is so simpler to understand how a function is related to threads.
Lastly this rewrite is the base for future code consolidations and
semplifications that are easier now that we have only one thread's
access point.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Ensure threads are sleeping when leaving init_threads() and
the newly introduced put_threads_to_sleep().
Also ensure threads are not sleeping when leaving
wake_sleeping_threads().
As a side effect we now leave think() with all the threads
(but the main one) guaranteed to sleep. So when we enter
again in think(), after the opponent next move, we know
threads must be sleeping.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Wait inside wake_sleeping_threads() for the threads to be
effectively and reliably woken up.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Will be used by future patches. Also:
- Renamed Idle in AllThreadsShouldSleep
- Explicitly inited AllThreadsShouldExit and AllThreadsShouldSleep
in init_thread() instead of use an anonymous global initialization.
- Rewritten idle_loop() while condition to avoid a 'break' statement
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Patch from Richard Lloyd (slightly edited from me), following the list
of changes as described by the author:
src/Makefile:
- Added PREFIX and BINDIR for the install: rule.
- Added a "make hpux" line to the help: rule.
- Added "make test"/"make check" rule that runs the $(PGOBENCH) command.
- "make clean" now additionally removes core and bench.txt.
- Added an hpux: rule.
- Added an install: rule to mkdir $(BINDIR), copy $(EXE) to $(BINDIR) and
then strip it.
- "make strip" now ensures that $(EXE) is built first before trying to
strip it.
- Hide errors and output from the g++ command used by the .depend: rule and
then touch .depend in case g++ isn't available.
- Hide errors from the "include .depend" in case .depend doesn't exist
(e.g. directly after a "make clean").
src/book.cpp and src/book.h:
- HP-UX's aCC really didn't like the const keywords used for the
Book::file_name() definitions, so they were removed. I checked that this
didn't affect a Linux build and it was still fine.
src/misc.cpp:
- HP-UX uses <sys/pstat.h> and pstat_getdynamic() to determine the number of
CPU cores, so added conditional code for that (if pstat_getdynamic() fails,
set the number of cores to 1).
src/tt.cpp:
- <xmmintrin.h> and _mm_prefetch() seem highly specific to the Intel x86(_64)
and gcc platforms - neither exist in HP-UX, so conditionally avoid that
code in HP-UX's case. Perhaps some sort of define is needed here
such as -DHAS_MM_PREFETCH that could be #ifdef'ed for instead?
Even after these changes, it's more convenient for HP-UX users to edit the
default: rule in the Makefile to run "$(MAKE) hpux" before they build
stockfish, but that's not a big deal if they're warned about that first (the
same applies to all other builds other than the standard "$(MAKE) gcc" one).
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Compiler complains because in Book we have a d'tor but not
copy c'tor and assignement operator (warning C4511 and C4512),
note that after adding them (just declared) you now need also
default c'tor !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is an hidden bug waiting to fire. The main problem is
that ss[ply] is overwritten by search() and qsearch() called
from IID and razoring, so that we cannot hold a pointer to a
local EvalInfo variable.
For instance if we go razoring then we overwrite the pointer
with the address of a variable local to qsearch(), when we return
from qsearch() variable goes out of scope and now ss[ply].evalInfo
holds a stale pointer !
Because we are not looking for troubles we go through the
safe route and we remove it entirely.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Gain value is multiplied by 16 to be of comparable magnitudo
of negative history, on average.
This patch shows very good results in tactical tests, but
started very bad in real games, so I have run two test matches.
After 896 games at 1+0
Mod vs Orig +187 =525 -184 +1 ELO
After 999 games at 1+0
Mod vs Orig +223 =590 -186 +13 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We can do this only when needed, if we get a cut-off
before we skip sorting entirely. This reduces sorting
time of about 20%.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In search routines we use information from previous ply
and init killers two plies ahead.
So for me it seems correct to copy 4 searchstack items
in split:
ply - 1, ply, ply + 1, ply + 2
Because
a) we do not split at root (ply == 0)
b) ply < PLY_MAX and SearchStack size is PLY_MAX_PLUS_2
there should be no risk of underflows or overflows
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With negative history we don't have anymore a
lot of zeroes to score, so just split moves in
positives and non-positives sets.
Speed up is almost zero, we cannot test speed directly
because node count changed due to reorder, but I have
verified sorting is correct. With a profiler I have
seen we gain a little in sort_moves() and lose a little
in insertion_sort(), so the net effect is almost zero,
but code is simpler.
No real change, just move reordering.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It was only used to control StopOnPonderHit variable.
Now use FailLow variable instead.
Patch has a minor effect on time management when ponder is on.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
noProblemFound condition is never true.
This was verified by running 800 games 1+0 match in 1 CPU computer.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Because H.move_ordering_score() can return negative values
some negative see moves could be searched before non-negative
see moves with negative history.
This patch restores proper ordering.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that history can go negative and is almost alwyas
non zero we have no more reasons to use also psqt term.
After 994 games at 1+0
Mod vs Orig +204 =597 -193 +4 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of piece-from-to, in this way it is similar
to what we already do for history.
Almost no change, but seems a bit simpler in this way.
After 995 games at 1+0
Mod vs Orig +207 =596 -192 +5 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems more standard conformant. Also added a bit of
description directly from Tord.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We erroneusly added two times the same scaling function
to endgame's map.
Fix detected by valgrind becasue resulted in a memleak
of the first added scaling function.
Bug introduced by 30e8f0c9ad6a473 of 13/02/2009
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We had an overflow due to use an integer for hash size,
now we use a size_t as we should, so we can increase to
an higher limit.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Normally it's up to the GUI to check for option's limits,
but we could receive the new value directly from the user
by teminal window. So let's check the bounds anyway.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With new target 'make gcc-popcnt' it is now
possible to compile with enabled hardware POPCNT
support also with gcc. Until now was possible only
for Intel and MSVC compilers.
When this instruction is supported by CPU, for instance
on Intel i7 or i5 family, produced binary is a bit faster.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This reverts commit c43c5fe9e0.
Produces following build error after 'make clean', 'make icc' under Mandriva
with icc version 11.0
Makefile:306: .depend: No such file or directory
In file included from tt.cpp:28:
/usr/lib/gcc/i586-manbo-linux-gnu/4.3.2/include/xmmintrin.h:35:3: error: #error "SSE instruction set not enabled"
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Futility captures alone does not seem an improvment.
Perhaps is a combination of stand pat + futility that is winning,
so revert for now and continue testing starting from a standard
base until we find the correct receipe.
After 999 games at 1+0
Mod vs Orig +231 0506 -201 +10 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Under some rare cases we can have a search tree explosion
due to a perpetual check or to a very long non-capture TT
sequence.
This avoids the tree explosion not following TT moves that
are not captures or promotions when we are below the
'generate checks' depth.
Idea suggested by Richard Vida.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Not a biggie but is a reduced pruned patch that doesn't
seems to hurt, so it is welcomed ;-)
After 999 games at 1+0
Mod vs Orig +207 =601 -191 +6 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
At ply == OnePly (common case) we avoid some useless
floating point computation.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Previously input like "setoption name Use Search Log value true "
(note space at the end of the line) didn't work.
Now parse value same way as option name. This way we implicitly
left- and right-trim value.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Initializing high-level object at startup is very dangerous,
because low-level snippets are not yet initialized.
For example Position's constructor calls find_checkers() which
calls attackers_to() which depends on various global bitboard arrays
which are not yet initialized. I think we are lucky not to crash.
RootPosition.from_fen(StartPosition); is called immediately after
all initializations are made at uci_main_loop() which is the
correct behaviour
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Joona new aspiration window. Main idea is to always
research aspiration fail highs/low at the same
ply and use much smaller aspiration window than previously.
Testing result is very positive.
1CPU:
953-1149
4CPU:
545 - 656
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Avoid to take the lock two times in a tight sequence, the first
in get_next_move() and the second to update sp->moves.
Do all with one lock and so retire the now useless locked version
of get_next_move().
Also fix some theorical race due to comparison sp->bestValue < sp->beta
is done out of lock protection. Finally fix another (harmless but time
waster) race that coudl occur because thread_should_stop() is also
called outside of lock protection.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In debug run with 2 threads it happens to be following
assert after some minutes:
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
in search(), line 1615.
I am not able to understand why, anyhow reverted for the moment.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This avoid us to forget some very needed tests now that
futility has changed in a whole big chunk we need to fine
tuning every splitted change.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This will be useful to use gains table in move
ordering along with history table.
No functional change and big code remove.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
With current search control system, I can see absolutely no
reason to classify fixed time search as infinite search.
So remove old dated hack
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Value of uip.eof() should not be trusted.
input like "go infinite searchmoves " (note space in the end of line)
causes problems.
Check the return value of (uip >> token) instead
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In less then 1% of cases value > sp->bestValue, so avoid
an useless lock in the common case. This is the same change
already applied to sp_search().
Also SplitPoint futilityValue is not volatile because
never changes after has been assigned in split()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When we have more then 2 threads then we do an array
access with index 'Threads[slave].activeSplitPoints - 1'
This should be >= 0 because we tested the variable just
few statements before, but because is a shared variable
it could be that the 'slave' thread set the value to zero
just after we test it, so that when we use the decremented
variable for array access we crash.
Bug spotted by Bruno Causse.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Unify start loop for master and slave threads. Also guarantee
that all the 'stop' flags are set to false before first slave
is started, should be no harm because only master thread can
reset 'stop' flag of slaves to true, so should be no race but
better safe then sorry.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Only pure blocking evasions are candidate
for pruning.
After 998 games at 1+0
Mod vs Orig +215 =596 -187 +10 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In move_to_san() we create by copy a new position just
to detect if move gives check. This could be very costly in
line_to_san() that calls move_to_san() for every move, so
create the position only once and pass a reference to move_to_san()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When pondering threads are put to sleep, but when thinking
the threads are parked in idle_loop in a tight polling loop
checking for workIsWaiting falg.
So before we set the slave's flag workIsWaiting we have to
guarantee that all the slave data is already setup because
slave can start in any moment from there.
Rearrange the last loop to fix this race.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Once we have allocated our slave threads and we have removed
master from available threads we can safely remove the lock
so that the lenghty search stack copy operation will not
impact lock contention.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
A pointer is enough because after a split point has been
setup master and slaves thread end up calling sp_search() or
sp_search_pv() and here a full copy of split point position is
done again, note that even master does another copy (of itself)
and this is done before any do_move() call so that master Position
is never updated between split() and sp_search().
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And detach splitPoint Position from the master one.
So we duplicate StateInfo only once in split() instead
of one for each thread in sp_search
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Renamed a bit the functions to be more clear what
we actually are doing when we craete a Position object
and explained how StateInfo works.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also removed some trailing whitespaces and aligned
indentation to current standard.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Only the previous, the current and the next ply SearchStack
are copied.
This reduces split overhead especially at low depth (high ply)
and with many threads.
Possibly no functional change (it is not easy to prove in SMP)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The init_eval() function corrupted the static array castleRightsMask[]
in the Position class, resulting in instant crashes in most Chess960
games. Fixed by repairing the damage directly after the function is
called. Also modified the Position::to_fen() function to display
castle rights correctly for Chess960 positions, and added sanity checks
for uncastled rook files in Position::is_ok().
It is a good programming practice to verify a system
call has indeed succeed.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When a search fails high then sp->alpha is increased and
slave threads are requested to stop.
So we have to check for a stop request before to start a search
otherwise we could end up with sp->alpha >= sp->beta
leading to an assert in debug run in search_pv().
This patch fixes the assert and get rid of some of possible races.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
maximum depth during a "go movetime ..." search. This prevents
Stockfish from hanging forever after finding a mate in two or
three while running a test suite at a level of a few seconds
per move.
No functional change when playing games at normal time controls.
In qsearch() try to get a cutoff with the help of an
extra check if we are already very near.
Small increase in actual games but a good result in tactical
test sets where this patch makes SF more tactical.
Mod vs Orig +197 =620 -181 +6 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Louis Zulli reports a miscompile with g++-4.4 from MacPorts.
Namely enum Value is compiled as unsigned instead of signed integer
and this yields an issue in score_string() where float(v) is incorrectly
casted when Value v is negative.
This patch ensure that compiler choses a signed variable to store a Value.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Value is never used un-initialized, but MSVC is not
smart enough to detect itself :-(
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use the same scoring system used for evasions. Small if any
increase, but should be in at least for completeness.
After 999 games at 1+0
Mod vs Orig +208 =601 -190 +6 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we have position static score we don't
need to call evaluate() a second time.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This will allow to have wider access to attack
information, for instance from MovePicker.
Note that 'eval' field become obsolete, it is kept
just becasue when we get a position score from TT
we update 'eval' even without an EvalInfo object.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In sp_search_pv() we do a LMR search using sp->alpha, at the end
we detect a fail high with condition (value > sp->alpha), but if
another thread has increased sp->alpha during our LMR search we
could miss to detect a fail high event becasue value will be equal
to old alpha and so smaller then new one.
This patch fixes this SMP-bug and changes also the non SMP versions
of the search to keep code style in sync.
Bug spotted by Bruno Causse.
No functional change (for single CPU case)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
futilityValue is now calculated immediately after
staticValue, so remove small bunch of unused code
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
MSVC raises an "use of partially uninitialized variable" for futilityValue
and staticValue but this is not rue becasue when !isCheck variables
are never used, anyhow silence the warning.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is less prone to bugs because now it's up to the
compiler don't forget this important initialization.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
No change in functionality signature
The only functional change is that when we reach PLY_MAX,
we now return VALUE_DRAW instead of evaluating position.
But we reach PLY_MAX only when position is dead drawn and
transposition table is filled with draw scores, so this
shouldn't matter at all.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This way razoring is always based on exact evaluation and
follows simple formula.
Joona's test results are positive:
32-bit 1CPU:
Mod - Orig: 1073 - 993
64-bit 4CPU:
Mod - Orig: 759 - 721
Functionality Signature: 11448962
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Don't clamp to zero if a move continues to fail.
After 946 games at 1+0
Mod vs Orig +208 =562 -176 +12 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Also retire razoring margins vector and use
a simpler formula instead.
Now that we use a more accurate static evaluation
try to avoid useless null searches when we are well
below beta. And for teh same reason increase a bit
the razoring.
After 972 games at 1+0
Mod vs Orig +224 =558 -190 +12 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It means we have already received "stop" or "quit" commands.
This fixes an hang in tactical test in Fritz GUI. Bug
introduced by previous bug fix :-(
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
According to UCI standard once engine receives 'go infinite'
command it should search until the "stop" command and do not exit
the search without being told so, even if PLY_MAX has been reached.
Patch is quite invasive because it cleanups some hacks used
by fixed depth and fixed nodes modes, mainly during benchmarks.
Bug found by Pascal Georges.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After deep tests Louis Zulli found on his OCTAL machine that
best setup for an 8 core CPU is as following
"Threads" = 8
"Minimum Split Depth" = 6 or 7 (mSD)
"Maximum Number of Threads per Split Point" = not important (MNTpSP)
Here are testing results:
mSD7 (8 threads) vs mSD4 (8 threads): 291 - 120 - 589
mSD6 vs mSD7: 168 - 188 - 644
mSD6-MNTpSP5 vs mSD6-MNTpSP6: 172 - 172 - 656
SF-7threads vs SF-8threads: 179 - 204 - 617
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
So to have the same layout and be as much similar as
possible. The only functional change is that now we
try ttMove as first also in PV nodes and at the end
we save the ttMove, as it happens in search. This
should have almost zero impact on ELO but it seems
the correct thing to do.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This is an important design change because we know
compute evaluation in each node.
This is a 2.0 type change!
After 977 games at 1+0
Mod vs Orig +236 =538 -202 51.74% +12 ELO
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If after 'moves' there is a space then we crash.
The problem is that operator>>() trims whitespaces so that
after 'moves' has been extract we are still not at eof()
but remaining string contains only spaces. So that the next
extarction operation uip >> token ends up with unchanged token
value that remains 'moves', this garbage value is then feeded
to RootPosition.do_move() through move_from_string() that does
not detect the invalid move value leading to a crash.
This bug is triggered by Shredder 12 interface under Mac that
puts a space after 'moves' without any actual move list.
Bug fixed by Justin Blanchard
After reviewing UCI parsing code I spotted other possible weak
points due to the fact that we don't test if the last extract
operation has been succesful. So I have extended Justing patch
to fix the remaining possible holes in uci.cpp
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
According to standard en-passant is recorded in fen string regardless
of whether there is a pawn in position to make an en passant capture.
Instead internally we set ep square only if the pawn can be captured.
So teach from_fen() to correctly handle this difference.
Bug reported and fixed by Justin Blanchard.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Try to get a position evaluation better then
the quick one with the help of the TT table.
This allows the null search conditions and
chosen reductions to be more accurate.
After 908 games at 1+0
Mod vs Orig +209 =526 -173 +14 ELO
Functionality Signature: 16627355
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Linear rule, less aggressive then Dann's one.
It seems it scales well with depth. We will need to
verify against weaker engine if it keeps the score.
After 999 games at 1+0 on my Dual Core
Mod vs Orig +232 =534 -207 +9 ELO
After 1000 games by Martin Thoresen on his QUAD at 1+0
Mod vs Orig 521/479 52.10%
Functionality Signature: 17655312
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The most interesting thing is a bit of rewrite
and semplification in connected_moves()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is not useful becasue it is safe to call
get_next_move() multiple times when phase == PH_STOP
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Because that's the correct meaning. Note that also the
corresponding UCI option has been renamed.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After history accounting rewrite in 1.6, a small
tweak of history parameters seems positive.
Note that these are not to be considered the optimal
values, just a wild guess that proved good.
Finding the optimal values would require a much longer
testing time.
After 967 games at 1+0
Mod vs Orig 240 529 198 +15 ELO
Functionality Signature: 21222553
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
According to the standard, compiler is free to choose
the enum type as long as can keep its data.
Also cast to short and right shift are implementation
defined in case of a signed integer.
Normally all the compilers implement this stuff in
the "usual" way, but gcc with -O3 and -O2 pushes
aggressively the language to its limits to squeeze
even the last bit of speed. And this broke our
not 100% standard conforming code.
The fix is to rewrite the Score enum and the 16 bits
word extracting functions in a way that is 100% standard
compliant and with no speed regression on gcc and also on
the other compilers.
Verified it works on all compilers and with equivalent
functionality.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The compiler is allowed to chose the size of an enum variable
based on the values it is expected to store. So force the compiler
to use at least a 32 bit integer type for the Score.
MSVC and Intel do not change, while gcc under -O3 is affected
by this change.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We cannot cast a pointer type to an unrelated pointer type.
This is a violation of the strict aliasing rules.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is not clear why is not true, even in single thread
case, but as a matter of fact it is not!
So remove it.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.