hi friends,
I want to have two evaluations returned from my evaluation function one for the endgame and one for the middle game. By scaling these two values the value of the position will be calculated like fruit and stockfish do.
I am wondering, can this be done by using only one integer? eg the endgame value in bits 0-15 and the midgame value in the other bits? I have expirimented with this approach but i cannot get it to work. Especially negative values in least significant bits give problems.
any help appreaciated
two values in one integer
Moderators: hgm, Rebel, chrisw
-
- Posts: 31
- Joined: Tue Dec 07, 2010 11:19 pm
- Location: Holland
-
- Posts: 481
- Joined: Thu Apr 16, 2009 12:00 pm
- Location: Slovakia, EU
Re: two values in one integer
some clues can be found here: http://www.talkchess.com/forum/viewtopi ... 746#301746
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: two values in one integer
It can be done correctly, as discussed in detail in the thread given by Richard. In my opinion a struct with two 16-bit values can be handled easier and with less "headache".Pierre Bokma wrote:hi friends,
I want to have two evaluations returned from my evaluation function one for the endgame and one for the middle game. By scaling these two values the value of the position will be calculated like fruit and stockfish do.
I am wondering, can this be done by using only one integer? eg the endgame value in bits 0-15 and the midgame value in the other bits? I have expirimented with this approach but i cannot get it to work. Especially negative values in least significant bits give problems.
any help appreaciated
Code: Select all
struct Score {
int16_t mgPart;
int16_t egPart;
};
inline void setScore(Score & score, int16_t mg, int16_t eg) {
score.mgPart = mg;
score.egPart = eg;
}
inline void addScore(Score & score, int16_t mg, int16_t eg) {
score.mgPart += mg;
score.egPart += eg;
}
Score myScore = { 0, 0 };
addScore(myScore, RookOn7thRankBonusMG, RookOn7thRankBonusEG);
Sven
-
- Posts: 180
- Joined: Mon Sep 03, 2007 9:15 am
Re: two values in one integer
Have a look here too:
http://www.talkchess.com/forum/viewtopi ... =0&t=38523
I think there was another thread about problems compiling such tricks with the intel compiler, but I don't could not find it with a quick search.
http://www.talkchess.com/forum/viewtopi ... =0&t=38523
I think there was another thread about problems compiling such tricks with the intel compiler, but I don't could not find it with a quick search.
-
- Posts: 31
- Joined: Tue Dec 07, 2010 11:19 pm
- Location: Holland
Re: two values in one integer
Thanks so far. I have been thinking on a solution. The main problem is that the value in the lower bits can get negative and mess up that value. How about this solution: instead of start with a value of 0 we could start at say 1000. As long as the score for the evaluation is not beneath -1000 we dont get the problem. The only thing to do is to substract 1000 from the end value of the least significant bits.
I will try this sceme tomorrow. Any thougths about is?
I will try this sceme tomorrow. Any thougths about is?
-
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: two values in one integer
My feeling is that tricks like this complicate the code, while the potential gain is not very big.
It mainly looks like a cool and clever hack.
Note that I haven't actually tried to seriously do something like this. If I wanted to though, I would look at using SSE vector intrinsics instead of hacking things together myself.
It mainly looks like a cool and clever hack.
Note that I haven't actually tried to seriously do something like this. If I wanted to though, I would look at using SSE vector intrinsics instead of hacking things together myself.
-
- Posts: 31
- Joined: Tue Dec 07, 2010 11:19 pm
- Location: Holland
Re: two values in one integer
Wow, for a hobby programmer like me this does not sound very simple. I have no idea what SSE vector intrinsics means.Evert wrote:My feeling is that tricks like this complicate the code, while the potential gain is not very big.
It mainly looks like a cool and clever hack.
Note that I haven't actually tried to seriously do something like this. If I wanted to though, I would look at using SSE vector intrinsics instead of hacking things together myself.
Besides is looked at an old post were a part of Stockfish is quoted. I implemented this and it seems the work fine.
-
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: two values in one integer
Hobby or not has very little to do with it.Pierre Bokma wrote: Wow, for a hobby programmer like me this does not sound very simple. I have no idea what SSE vector intrinsics means.
I don't do this stuff for a living either.
It comes down to this: modern CPUs have instructions for handling vector addition/subtraction/multiplication, which means that instead of working on one value at a time, you can actually operate on more values in the same time. Compilers may be able to do it automatically for you, but you can also help them by using compiler-specific "intrinsic" functions. These work like any othe C library function, so you don't have to resort to hand-written assembly.
GCC has some nice compiler extensions for handling this type of object as well (which I found very useful for my general engine Sjaak). Then you can actually use normal operators without having to go to C++ and use operator overloading.
It'll work. That doesn't mean it's not a hack though.Besides is looked at an old post were a part of Stockfish is quoted. I implemented this and it seems the work fine.
-
- Posts: 3232
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: two values in one integer
100% agree. That's what I do and use bit fields heavily, rather than doing things in a horrible manual way. Some say there's a performance, but I've never noticed it, using gcc 4.6.1Sven Schüle wrote:It can be done correctly, as discussed in detail in the thread given by Richard. In my opinion a struct with two 16-bit values can be handled easier and with less "headache".Pierre Bokma wrote:hi friends,
I want to have two evaluations returned from my evaluation function one for the endgame and one for the middle game. By scaling these two values the value of the position will be calculated like fruit and stockfish do.
I am wondering, can this be done by using only one integer? eg the endgame value in bits 0-15 and the midgame value in the other bits? I have expirimented with this approach but i cannot get it to work. Especially negative values in least significant bits give problems.
any help appreaciatedHard to beat in terms of coding effort, correctness, and runtime performance.Code: Select all
struct Score { int16_t mgPart; int16_t egPart; }; inline void setScore(Score & score, int16_t mg, int16_t eg) { score.mgPart = mg; score.egPart = eg; } inline void addScore(Score & score, int16_t mg, int16_t eg) { score.mgPart += mg; score.egPart += eg; } Score myScore = { 0, 0 }; addScore(myScore, RookOn7thRankBonusMG, RookOn7thRankBonusEG);
Sven
But yes, as mentionned by Richard, if you do things manually, your headache isn't over Just wait until your code works on one compiler and not another, or is endianness dependant... I strongly advise you to follow Sven's route
-
- Posts: 153
- Joined: Fri Sep 30, 2011 7:48 am
Re: two values in one integer
You could also copy, bitshift to remove the un-needed numbers and type-cast.
i.e. the slow way for 32 bit integers with left shifting multiplying by 2^k
or the struct method outlined by Sven, or otherwise something like ...
[/code]
i.e. the slow way for 32 bit integers with left shifting multiplying by 2^k
Code: Select all
int temp_num = packed_value ;
temp_num = temp_num << 16;
temp_num = temp_num >> 16;
int lower_part = temp_num;
temp_num = packed_value;
temp_num = temp_num >> 16;
int upper_part = temp_num;
Code: Select all
class UnionType
{
union
{
struct
{
int value;
};
struct
{
int16 lower;
int16 upper;
};
};
};