Two doubts

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
Kempelen
Posts: 620
Joined: Fri Feb 08, 2008 10:44 am
Location: Madrid - Spain

Two doubts

Post by Kempelen »

I programmed a chess engine a few years ago, now I am starting to make one from zero.
As I am designing now and taking firsts decisions, I would like to know:

1) What is more efficient, a struct with move details, or coding the entire move into a int? why? or other system...?

2) if I generate moves for a possition, then in the search process, would it be necesary to store thems for other places in the search? , or it will only be needed in only in one occasion? I ask this to desing a good move representation system that could store them. I want to understand why

thx in advance
FS
Dann Corbit
Posts: 12777
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: Two doubts

Post by Dann Corbit »

Kempelen wrote:I programmed a chess engine a few years ago, now I am starting to make one from zero.
As I am designing now and taking firsts decisions, I would like to know:

1) What is more efficient, a struct with move details, or coding the entire move into a int? why? or other system...?
They are equivalent.

2) if I generate moves for a possition, then in the search process, would it be necesary to store thems for other places in the search? , or it will only be needed in only in one occasion? I ask this to desing a good move representation system that could store them. I want to understand why
It is possible to hash generated moves but since move generation is usually very fast it won't matter much.

thx in advance
FS
My opinion is that you should write code that is the most clear and expressive that you can possibly generate. The things that make a chess program fast or slow are algorithmic changes. The nitty-gritty details are usually not very important. And in those few circumstances where they do become important, a profile will reveal it and you can fix the hot spots as you find them.

In general, I think it is a bad idea to try to outhink the compiler. Just write the best code you know how to write and try to think of algorithmic inclusions.

As an example, if you can reduce the branching factor of your engine by 0.25 that will be far more important than tripling the speed of your move generator.
User avatar
ilari
Posts: 750
Joined: Mon Mar 27, 2006 7:45 pm
Location: Finland

Re: Two doubts

Post by ilari »

Kempelen wrote:What is more efficient, a struct with move details, or coding the entire move into a int? why? or other system...?
In Sloppy I use an unsigned int, and not just for speed. It allows me to do comparisons like "move1 == move2", and pass moves to functions by value without worrying about speed. It's also a compact structure, which means that I can have more hash entries or a smaller transposition table. With that said, I think my program would be pretty much just as strong had I chosen to use a struct. I would've just designed some things differently.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Two doubts

Post by bob »

Dann Corbit wrote:
Kempelen wrote:I programmed a chess engine a few years ago, now I am starting to make one from zero.
As I am designing now and taking firsts decisions, I would like to know:

1) What is more efficient, a struct with move details, or coding the entire move into a int? why? or other system...?
They are equivalent.
They might not be equivalent. If he is talking about bit-fields, sometimes they can cause problems because the compiler might attempt sign-extension when it is not needed. And accessing the upper end of the move can be done by the programmer with a simple right shift, where the compiler won't know that the remaining bits are zero and will AND them away when they are already zero.

Also I have found a few other efficiency issues. For example, "is this a promotion or capture?" That can be answered by just ANDing off everything but the 3 bits for the captured piece and the 3 bits for the promotion-to piece, and if the result is non-zero, we are done. Using the bitfields I started with would not allow this.


2) if I generate moves for a possition, then in the search process, would it be necesary to store thems for other places in the search? , or it will only be needed in only in one occasion? I ask this to desing a good move representation system that could store them. I want to understand why
It is possible to hash generated moves but since move generation is usually very fast it won't matter much.

thx in advance
FS
My opinion is that you should write code that is the most clear and expressive that you can possibly generate. The things that make a chess program fast or slow are algorithmic changes. The nitty-gritty details are usually not very important. And in those few circumstances where they do become important, a profile will reveal it and you can fix the hot spots as you find them.

In general, I think it is a bad idea to try to outhink the compiler. Just write the best code you know how to write and try to think of algorithmic inclusions.

As an example, if you can reduce the branching factor of your engine by 0.25 that will be far more important than tripling the speed of your move generator.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Two doubts

Post by sje »

The answer is that a program can use more than one move representation. A fast one for searching and a compact one for transposition table storage are two examples.

Two warnings about using compiler assigned bit fields in structs:

1) There is no standard for allocation emplacement. The same compiler can generate different layouts for the same struct with bit fields for two different target architectures. This can be a problem if the data is externalized and shared.

2) It is very likely, almost certain, that the generated code for bit field access is going to be longer and slower than custom inline functions.
mathmoi
Posts: 290
Joined: Mon Mar 13, 2006 5:23 pm
Location: Québec
Full name: Mathieu Pagé

Re: Two doubts

Post by mathmoi »

sje wrote:The answer is that a program can use more than one move representation. A fast one for searching and a compact one for transposition table storage are two examples.

Two warnings about using compiler assigned bit fields in structs:

1) There is no standard for allocation emplacement. The same compiler can generate different layouts for the same struct with bit fields for two different target architectures. This can be a problem if the data is externalized and shared.

2) It is very likely, almost certain, that the generated code for bit field access is going to be longer and slower than custom inline functions.
Hi

I just tried this yesterday, I replaced my compiler assigned bitfields with an unsigned int that I was manipulating "mannualy". With g++ on a Athlon 64 CPU I was unable to measure any performance gain from doing it mannualy. Actually it was a bit slower by about 0.2% (not significant).