crafty-22.0

Discussion of chess software programming and technical issues.

Moderator: Ras

bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: crafty-22.0

Post by bob »

jwes wrote:The PV length is the only one that concerns me.
OK, I have at least fixed the PV for searches, and the egtb PV output. new command is "linelength=n" with a default value of 80..
Guetti

Re: crafty-22.0

Post by Guetti »

bob wrote: Here is what I get on the make linux-amd64 on my suse laptop:

scrappy% make linux-amd64
make target=LINUX \
CC=gcc CXX=g++ \
CFLAGS=' -Wall -pipe \
-fbranch-probabilities -fomit-frame-pointer -O3 -march=k8' \
CXFLAGS= \
LDFLAGS=' -lnuma -lstdc++' \
opt=' -DINLINE64 -DCPUS=8 -DNUMA -DLIBNUMA' \
crafty-make
make[1]: Entering directory `/home/hyatt/crafty'
make[2]: Entering directory `/home/hyatt/crafty'
gcc -Wall -pipe \
-fbranch-probabilities -fomit-frame-pointer -O3 -march=k8 -DINLI
NE64 -DCPUS=8 -DNUMA -DLIBNUMA -DLINUX -c crafty.c
crafty.c: In function ‘ValidatePosition’:
crafty.c:46: note: file crafty.gcda not found, execution counts estimated
g++ -c -DINLINE64 -DCPUS=8 -DNUMA -DLIBNUMA -DLINUX egtb.cpp
egtb.cpp:4478: warning: ‘TB_CRC_CHECK’ initialized and declared ‘extern’
gcc -lnuma -lstdc++ -o crafty crafty.o egtb.o -lm
make[2]: Leaving directory `/home/hyatt/crafty'
make[1]: Leaving directory `/home/hyatt/crafty'

It also ran just fine...
Just as a side note, from your compile output above I see something that I see on my UNIX machines too when I use gcc to compile crafty:
the CFLAGS specified in the Makefile (in your case ' -Wall -pipe -fbranch-probabilities -fomit-frame-pointer -O3 -march=k8') do not get passed to CXFLAGS and g++, at least according to the output of make:

g++ -c -DINLINE64 -DCPUS=8 -DNUMA -DLIBNUMA -DLINUX egtb.cpp
egtb.cpp:4478: warning: ‘TB_CRC_CHECK’ initialized and declared ‘extern’

Is this an error in the output of make, and they are used anyway or are they somehow lost? Wouldn't the absence of any optimization flags slow down the EGTB access? Maybe you can answer once the biggest hubbub about the new version is past.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: crafty-22.0

Post by bob »

Guetti wrote:
bob wrote: Here is what I get on the make linux-amd64 on my suse laptop:

scrappy% make linux-amd64
make target=LINUX \
CC=gcc CXX=g++ \
CFLAGS=' -Wall -pipe \
-fbranch-probabilities -fomit-frame-pointer -O3 -march=k8' \
CXFLAGS= \
LDFLAGS=' -lnuma -lstdc++' \
opt=' -DINLINE64 -DCPUS=8 -DNUMA -DLIBNUMA' \
crafty-make
make[1]: Entering directory `/home/hyatt/crafty'
make[2]: Entering directory `/home/hyatt/crafty'
gcc -Wall -pipe \
-fbranch-probabilities -fomit-frame-pointer -O3 -march=k8 -DINLI
NE64 -DCPUS=8 -DNUMA -DLIBNUMA -DLINUX -c crafty.c
crafty.c: In function ‘ValidatePosition’:
crafty.c:46: note: file crafty.gcda not found, execution counts estimated
g++ -c -DINLINE64 -DCPUS=8 -DNUMA -DLIBNUMA -DLINUX egtb.cpp
egtb.cpp:4478: warning: ‘TB_CRC_CHECK’ initialized and declared ‘extern’
gcc -lnuma -lstdc++ -o crafty crafty.o egtb.o -lm
make[2]: Leaving directory `/home/hyatt/crafty'
make[1]: Leaving directory `/home/hyatt/crafty'

It also ran just fine...
Just as a side note, from your compile output above I see something that I see on my UNIX machines too when I use gcc to compile crafty:
the CFLAGS specified in the Makefile (in your case ' -Wall -pipe -fbranch-probabilities -fomit-frame-pointer -O3 -march=k8') do not get passed to CXFLAGS and g++, at least according to the output of make:

g++ -c -DINLINE64 -DCPUS=8 -DNUMA -DLIBNUMA -DLINUX egtb.cpp
egtb.cpp:4478: warning: ‘TB_CRC_CHECK’ initialized and declared ‘extern’

Is this an error in the output of make, and they are used anyway or are they somehow lost? Wouldn't the absence of any optimization flags slow down the EGTB access? Maybe you can answer once the biggest hubbub about the new version is past.
I am actually not sure. I didn't write this particular Makefile, and have never liked the recursive use. I may well just rewrite the thing in a straightforward fashion as it appears that the CFLAGS/CXFLAGS don't get passed properly...
Uri Blass
Posts: 10792
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: crafty-22.0

Post by Uri Blass »

bob wrote:
Uri Blass wrote:
bob wrote:The source is now up on the ftp box. While it is pretty clean, it is not the "finished product" yet. Additional cleanup will happen over the next few versions...

Feedback is welcome if there are any compiling issues that crop up. It works fine under gcc and intel's c compiler on linux, and a couple have compiled it on MSVC as well, so it should pose no problems...
looking at the move generator I see the following part repeats again and again and I wonder if you plan to replace it or something bigger by a function as part of the additional cleanup.

Code: Select all

while (moves) {
      to = Advanced(wtm, moves);
      *move++ = temp | (to << 6) | (Abs(PcOnSq(to)) << 15);
      Clear(to, moves);
    }
    Clear(from, piecebd);
Uri
I can already eliminate all of that, not just the part to extract the moves and stuff 'em in an array. But I have not done so yet. Eventually I will have one loop to generate moves for all pieces, and one loop to generate moves for pawns (which are different enough to make it not worthwhile to try to share any code).

As I mentioned, there is a lot of cleanup left to do now that the basic infrastructure is present to eliminate the duplication.

Replacing the above with a function is really pointless, because the function just get inlined and there is no performance gain at all. But collapsing all piece move generations into one loop will shrink the size of the code and have a positive impact...

If you look at make/unmake, you will not see anything duplicated between different piece types, and that is my goal for movgen as well...
I wonder if there are cases when programmers need to write the same code again and again in order to do things faster.

The reason is that I found that in strelka some code of the move generator repeats again and again but when I tried to replace it by a function the code was slower

I guess that the reason is that the code that repeat is of the type
for(b=BitBoard1,b!=0,b&=b-1)
{
do X with score=10
}
for(b=BitBoard2,b!=0,b&=b-1)
{
do X with score=11
}
for(b=BitBoard3,b!=0,b&=b-1)
{
do X with score=12
}


often b=0 so giving the score to some function is a waste of time.

I could probably make the code faster without loss of speed by code of the type
for(b=BitBoard1,b!=0,b&=b-1)
f(...,10);
for (b=BitBoard2,b!=0,b&=b-1)
f(...,11);

The problem is that I do not like to repeat again and again b!=0 b&=b-1 so I gave the function also b and made it slower and I wonder if there is a way to write it in a more elegant way without making it slower.
I want to have some function that get BitBoard1 and get other variables but look at the value of the other variables only if BitBoard1!=0

I guess that a smart compiler should do it without help but I also guess that the compiler that I use is not smart enough(or maybe there was a different reason that the program became slightly slower)

Uri
wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 5:03 pm
Location: British Columbia, Canada

Re: crafty-22.0

Post by wgarvin »

Uri Blass wrote:I guess that a smart compiler should do it without help but I also guess that the compiler that I use is not smart enough(or maybe there was a different reason that the program became slightly slower)
The compiler may not want to inline your function for some reason. When that happens, you can usually force it to inline it anyway using some compiler-specific declaration or keyword. For MSVC I think its "__forceinline".
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: crafty-22.0

Post by bob »

Uri Blass wrote:
bob wrote:
Uri Blass wrote:
bob wrote:The source is now up on the ftp box. While it is pretty clean, it is not the "finished product" yet. Additional cleanup will happen over the next few versions...

Feedback is welcome if there are any compiling issues that crop up. It works fine under gcc and intel's c compiler on linux, and a couple have compiled it on MSVC as well, so it should pose no problems...
looking at the move generator I see the following part repeats again and again and I wonder if you plan to replace it or something bigger by a function as part of the additional cleanup.

Code: Select all

while (moves) {
      to = Advanced(wtm, moves);
      *move++ = temp | (to << 6) | (Abs(PcOnSq(to)) << 15);
      Clear(to, moves);
    }
    Clear(from, piecebd);
Uri
I can already eliminate all of that, not just the part to extract the moves and stuff 'em in an array. But I have not done so yet. Eventually I will have one loop to generate moves for all pieces, and one loop to generate moves for pawns (which are different enough to make it not worthwhile to try to share any code).

As I mentioned, there is a lot of cleanup left to do now that the basic infrastructure is present to eliminate the duplication.

Replacing the above with a function is really pointless, because the function just get inlined and there is no performance gain at all. But collapsing all piece move generations into one loop will shrink the size of the code and have a positive impact...

If you look at make/unmake, you will not see anything duplicated between different piece types, and that is my goal for movgen as well...
I wonder if there are cases when programmers need to write the same code again and again in order to do things faster.

The reason is that I found that in strelka some code of the move generator repeats again and again but when I tried to replace it by a function the code was slower
This should not happen. Compilers are very good at inlining, assuming the function to be inlined is compiled at the same time (and in the same source file) as the function doing the calling. Inlining should produce identical results compared to replicated code, if inlined properly.

I have some duplicated code in movgen still (besides the part you pointed out) because I hate to use an array of pointers to functions to generate the moves for each piece, so that I can just do "temp=generatemoves(piece)" where I now have 5 blocks of code, one for each type of piece (pawns don't fit here because of their special stuff including promotions and enpassant and 1/2 square advances, etc..) I will probably test that as it would really shrink things, but I am afraid it might slow things down just a bit, but I am going to test this hypothesis.

I guess that the reason is that the code that repeat is of the type
for(b=BitBoard1,b!=0,b&=b-1)
{
do X with score=10
}
for(b=BitBoard2,b!=0,b&=b-1)
{
do X with score=11
}
for(b=BitBoard3,b!=0,b&=b-1)
{
do X with score=12
}


often b=0 so giving the score to some function is a waste of time.

I could probably make the code faster without loss of speed by code of the type
for(b=BitBoard1,b!=0,b&=b-1)
f(...,10);
for (b=BitBoard2,b!=0,b&=b-1)
f(...,11);

The problem is that I do not like to repeat again and again b!=0 b&=b-1 so I gave the function also b and made it slower and I wonder if there is a way to write it in a more elegant way without making it slower.
I want to have some function that get BitBoard1 and get other variables but look at the value of the other variables only if BitBoard1!=0

I guess that a smart compiler should do it without help but I also guess that the compiler that I use is not smart enough(or maybe there was a different reason that the program became slightly slower)

Uri
You can always try the force_inline option, but the main thing that some overlook is to put the function being called in x.c, and then calling it in y.c, and compiling each of those separately. No way the calls can be inlined. If both files are combined, then inlining can work...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: crafty-22.0

Post by bob »

wgarvin wrote:
Uri Blass wrote:I guess that a smart compiler should do it without help but I also guess that the compiler that I use is not smart enough(or maybe there was a different reason that the program became slightly slower)
The compiler may not want to inline your function for some reason. When that happens, you can usually force it to inline it anyway using some compiler-specific declaration or keyword. For MSVC I think its "__forceinline".
One common reason is code size. Compilers consider the size of the object code produced, and a significant function called many times won't be inlined because of the resultant executable size getting inflated. But, you can always force it to inline...
Cardoso
Posts: 363
Joined: Thu Mar 16, 2006 7:39 pm
Location: Portugal
Full name: Alvaro Cardoso

Re: crafty-22.0

Post by Cardoso »

This is perhaps a fault of the C language and a sugestion to make to compiler manufacturers, don't you think?

Alvaro
Guetti

Re: crafty-22.0

Post by Guetti »

Does somebody have good compile options for crafty using the latest Intel compiler 10.1.012 on linux for amd64/Opteron?
I tried make linux-icc but the compiler tells me that -xN and -Ob2 are not supported anymore.
An can I just compile with 'make profile'?
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: crafty-22.0

Post by bob »

Cardoso wrote:This is perhaps a fault of the C language and a sugestion to make to compiler manufacturers, don't you think?

Alvaro
I don't see how it could be fixed. If you compile a.c by itself, how could the compiler possibly inline a function from b.c into a.c since it is not looking at b.c?

The solution I use in Crafty is to have a crafty.c file that is nothing but a bunch of #includes that include every c module in the program. Now, since all the procedures are visible to the compiler in one pass, it can inline whatever it wants. But still, memory is an issue and compilers will not unroll/inline everything because of the resulting code size, although you can force whatever you want if you don't care...