On linux, I don't see the 1 minute initialization. The first time is slower, but each time after that sees crafty starting up instantly. I'm probably going to move to syzygy because at least that works according to the current moves, where Nalimov reports mates that you can't reach within 50 moves, as well as the case where you have a longer win that doesn't reach the 50 move rule, but the nalimov tables take you to a shorter mate that draws by 50 move rule.Joost Buijs wrote:Templates are not the Holy Grail and you have to use them wisely, it won't hurt to use them on occasion to get better maintainable code.bob wrote:You should look at what templates do in Eugene's "egtb.cpp" c++ code. It takes longer to compile that code than it does to compile the rest of the crafty source. Crafty source is 40K lines of code with comments, egtb.cpp is about 6600 lines of code. Yet egtb compiles into 2x the code that is in Crafty.Joost Buijs wrote:I don't know what is worse, the increased cache footprint or the added branches (which will also increase the cache footprint somewhat).bob wrote:Don't forget templates also increase the cache footprint, which is another performance loss.Joost Buijs wrote:Duplicating things is bad practice because it is difficult to maintain, I agree.bob wrote:You can still structure things reasonably cleanly. But when you duplicate code, you invite bugs. My evaluation could be a bit faster with separate cases for white and black. But back to that having to change two different pieces of code problem. Having done it both ways, I prefer zero duplication when practical.Joost Buijs wrote:By merging everything in the search the source code will shrink by a factor 2 or 3 but the readability will be less, now every function is very well defined and readable.bob wrote: That is THE reason I discontinued this bad practice several years ago.
I have a single Search() procedure, and a simple Quiesce() procedure. I have one special case, QuiesceEvasions() that I will get rid of pretty soon...
I'm sure that when I spend a few days on it that I can merge everything in let's say 3 functions, but I feel very reluctant to spend time on a cosmetic change.
Somehow I'm a little bit chess tired, I didn't touch my source code for the last 1,5 years besides fixing one or two bugs.
A couple of weeks ago I decided to revive my old Draughts program, I made a new bitboard move generator for it using magics and behold now it is 4 times faster compared to the old mailbox one.
This gives me a lot more fun because it is new, after 40 years of programming chess (with a break of 10 years) I feel like I have seen it all.
The PV and non PV code is different enough and not really a duplicate, but the SMP and non SMP code is almost a 100% duplicate besides some locking and atomic stuff.
When I want to change this I'll have to use templates (like in my evaluation function), otherwise the performance will be hurt by the additional if/then/else constructs.
On the other hand I don't see a reason why I would change this because the old code is more or less closed.
One way or the other, in practice it won't matter much, we are talking about speed differences of at most a few percent (a few Elo in strength).
The issue is that a few percent here, a few percent there, and you have programs that vary in NPS by a factor of 4.
What there is wrong with Nalimov EGTB I don't know, I never studied that code in detail, I only made some changes to it to make it compatible with modern C++ compilers.
It is true that it compiles horribly slow and that it generates huge binaries, without Nalimov my engine is 200 KB in size and with Nalimov it is 1.4 MB.
To be honest it is very messy code and it is a miracle that it works without many bugs.
The initialization is also very slow, when I use 6 men on SSD it still takes a minute or so for initialization.
Unfortunately there are not many alternatives, syzygy is probably faster, but I like to have distance to mate.
I like knowing the distance to mate, and I presume one can actually deliver that if they try, with some effort. Ie walk the PV to each conversion, and eventually you reach one that ends in mate. Sum 'em all up and you could produce the mate in N if you want to. Of course, that won't be the "shortest mate" but it will be a real mate that can be forced within the current 50 move rule. (A longer distance to conversion might lead to a shorter mate, obviously, and this would miss that unless one REALLY goes to some trouble.)