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
Two doubts
Moderator: Ras
-
- Posts: 12777
- Joined: Wed Mar 08, 2006 8:57 pm
- Location: Redmond, WA USA
Re: Two doubts
They are equivalent.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...?
It is possible to hash generated moves but since move generation is usually very fast it won't matter much.
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
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.
thx in advance
FS
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.
-
- Posts: 750
- Joined: Mon Mar 27, 2006 7:45 pm
- Location: Finland
Re: Two doubts
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.Kempelen wrote:What is more efficient, a struct with move details, or coding the entire move into a int? why? or other system...?
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: Two doubts
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.Dann Corbit wrote:They are equivalent.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...?
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.
It is possible to hash generated moves but since move generation is usually very fast it won't matter much.
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 whyMy 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.
thx in advance
FS
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.
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Re: Two doubts
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.
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.
-
- Posts: 290
- Joined: Mon Mar 13, 2006 5:23 pm
- Location: Québec
- Full name: Mathieu Pagé
Re: Two doubts
Hisje 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.
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).
Mathieu Pagé
mathieu@mathieupage.com
mathieu@mathieupage.com