two values in one integer

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Pierre Bokma
Posts: 31
Joined: Tue Dec 07, 2010 11:19 pm
Location: Holland

two values in one integer

Post by Pierre Bokma »

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
User avatar
rvida
Posts: 481
Joined: Thu Apr 16, 2009 12:00 pm
Location: Slovakia, EU

Re: two values in one integer

Post by rvida »

Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: two values in one integer

Post by Sven »

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
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".

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);
Hard to beat in terms of coding effort, correctness, and runtime performance.

Sven
Volker Annuss
Posts: 180
Joined: Mon Sep 03, 2007 9:15 am

Re: two values in one integer

Post by Volker Annuss »

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.
Pierre Bokma
Posts: 31
Joined: Tue Dec 07, 2010 11:19 pm
Location: Holland

Re: two values in one integer

Post by Pierre Bokma »

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?
User avatar
Evert
Posts: 2929
Joined: Sat Jan 22, 2011 12:42 am
Location: NL

Re: two values in one integer

Post by Evert »

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.
Pierre Bokma
Posts: 31
Joined: Tue Dec 07, 2010 11:19 pm
Location: Holland

Re: two values in one integer

Post by Pierre Bokma »

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.
Wow, for a hobby programmer like me this does not sound very simple. I have no idea what SSE vector intrinsics means.

Besides is looked at an old post were a part of Stockfish is quoted. I implemented this and it seems the work fine.
User avatar
Evert
Posts: 2929
Joined: Sat Jan 22, 2011 12:42 am
Location: NL

Re: two values in one integer

Post by Evert »

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.
Hobby or not has very little to do with it. ;)
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.
Besides is looked at an old post were a part of Stockfish is quoted. I implemented this and it seems the work fine.
It'll work. That doesn't mean it's not a hack though. ;)
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: two values in one integer

Post by lucasart »

Sven Schüle wrote:
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
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".

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);
Hard to beat in terms of coding effort, correctness, and runtime performance.

Sven
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.1

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
Dave_N
Posts: 153
Joined: Fri Sep 30, 2011 7:48 am

Re: two values in one integer

Post by Dave_N »

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

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;
or the struct method outlined by Sven, or otherwise something like ...

Code: Select all

class UnionType
&#123;
    union
    &#123;
        struct
        &#123;
            int value;
        &#125;;
        struct
        &#123;
            int16 lower;
            int16 upper;
        &#125;;
    &#125;;
&#125;;
[/code]