Special code for black and white

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

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

Special code for black and white

Post by Kempelen »

I have:

Code: Select all

if (color==WHITE) {
    evalWhite += evalSquareWhite(sq);
} else {
    evalBlack += evalSquareBlack(sq);
}
it is worth write on this why:

Code: Select all

eval[color] = evalSquare(color,aq)
These are only samples, where I use only one code for both colors, but during a lot of use like var[color].......

I am facing the choice of what kind of code like this to write for all my eval functions (and maybe other as well). It looks to me that second has the adventage of less code lines, but more processor time, isn't it? Do you have any ideas or advised on what model to use and why?
thx
Aleks Peshkov
Posts: 892
Joined: Sun Nov 19, 2006 9:16 pm
Location: Russia

Re: Special code for black and white

Post by Aleks Peshkov »

Disadvantage of separate code is bloating of generated machine code, advantage for separate code is possibility to avoid if (color==WHITE) completely.

Your both variants are similar and does not have advantages at all -- you duplicate both color test and color specific code. Test if (color==WHITE) is hidden in your evalSquare(color, sq) and in many other places.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Special code for black and white

Post by Sven »

I have code similar to this:

Code: Select all

enum { White=0, Black=1 };
//...
int someValue[2][BOARD_SIZE];
//...
inline int someEvalFunction(int color, int sq) {
    //...
    return someValue[color][sq];
}
This way I avoid both "if (color == White)" code and duplication of large code pieces. The extra cost is the extra dimension of arrays.

This was an early, major design decision for my engine. I know that there may be other important reasons to use different values for constants White and Black which may have other advantages.

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

Re: Special code for black and white

Post by bob »

Kempelen wrote:I have:

Code: Select all

if (color==WHITE) {
    evalWhite += evalSquareWhite(sq);
} else {
    evalBlack += evalSquareBlack(sq);
}
it is worth write on this why:

Code: Select all

eval[color] = evalSquare(color,aq)
These are only samples, where I use only one code for both colors, but during a lot of use like var[color].......

I am facing the choice of what kind of code like this to write for all my eval functions (and maybe other as well). It looks to me that second has the adventage of less code lines, but more processor time, isn't it? Do you have any ideas or advised on what model to use and why?
thx
I have done it both ways. The speed difference is not very significant, but for me, the second approach (less code) was actually a bit faster in Crafty. I made this conversion a couple of months back, primarily to simplify development and debugging. Having the same code duplicated (with different constants) for black and white leaves lots of places for errors to creep in and I thought it was about time to get rid of that. You will always have to have sets of constants for black/white since the squares are different, but xx[color] makes that pretty clean...
Harald Johnsen

Re: Special code for black and white

Post by Harald Johnsen »

Kempelen wrote:It looks to me that second has the adventage of less code lines, but more processor time, isn't it?
What makes you think that the second costs more cpu ?

Code: Select all

eval[W] = evalSquare(W,aq)
eval[B] = evalSquare(B,aq)
This code will be *exactly* as fast as the two duplicated functions where you manualy replaced color with W or B. Your function evalSquare must be declared inlined. Duplicating code is so old school.

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

Re: Special code for black and white

Post by Kempelen »

Harald Johnsen wrote:
Kempelen wrote:
This code will be *exactly* as fast as the two duplicated functions where you manualy replaced color with W or B. Your function evalSquare must be declared inlined. Duplicating code is so old school.

HJ.
What I was refering about, is not if one function is faster than two , but the code with var[x] or var_for_color. My code was not complete in the first post. Let see again:

Example 1:

Code: Select all

if (color==white) {
        evalWhite += some_code.....using the black piezes
        evalWhite += some_code.....using the white piezes
        17 operations more of this kind

} else {
        evalBlack += some_code.....using the white piezes
        evalBlack += some_code.....using the black piezes
        17 operations more of this kind
}
Example 2:

Code: Select all

        eval[color] += somecode[xturno]
        eval[color] += somecode[turno]
        17 more operations of this kind
In the first example, for a pieze, only a condition is done, with 19 operations "normal" operations without using dimensional arrays
In the second one, no condition is executed, but 19 operations using var[color] type, whitch mean that at execution time, 2 add operations has to be done per line
Is appear to me that example 2 is more time consuming.....
It will be the same if only a operation will be done inside the if statement, but it is not the case.

I think prof. Hyatt had better result with second type because the way and the order in whitch he evaluates positional characteristics is different to the example I am refering.....
Gerd Isenberg
Posts: 2250
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: Special code for black and white

Post by Gerd Isenberg »

Kempelen wrote: What I was refering about, is not if one function is faster than two , but the code with var[x] or var_for_color. My code was not complete in the first post. Let see again:

Example 1:

Code: Select all

if (color==white) {
        evalWhite += some_code.....using the black piezes
        evalWhite += some_code.....using the white piezes
        17 operations more of this kind

} else {
        evalBlack += some_code.....using the white piezes
        evalBlack += some_code.....using the black piezes
        17 operations more of this kind
}
Example 2:

Code: Select all

        eval[color] += somecode[xturno]
        eval[color] += somecode[turno]
        17 more operations of this kind
In the first example, for a pieze, only a condition is done, with 19 operations "normal" operations without using dimensional arrays
In the second one, no condition is executed, but 19 operations using var[color] type, whitch mean that at execution time, 2 add operations has to be done per line
Is appear to me that example 2 is more time consuming.....
It will be the same if only a operation will be done inside the if statement, but it is not the case.

I think prof. Hyatt had better result with second type because the way and the order in whitch he evaluates positional characteristics is different to the example I am refering.....
I vote for option 2 for better maintainability - to let the compiler do the whole optimization work by either instantiate sets of routines for white and black by inlining with actual const parameter or (explicitly) by template parameter.

At some point you need to call:

Code: Select all

evalStuff(white, ...);
evalStuff(black, ...);

if ( color == white )
   evalStuff(white, ...);
else
   evalStuff(black, ...);
or with int templates (not MSVC 6):

Code: Select all

evalStuff<white>(...);
evalStuff<black>(...);

if ( color == white )
   evalStuff<white>(...);
else
   evalStuff<black>(...);
Gerd
Harald Johnsen

Re: Special code for black and white

Post by Harald Johnsen »

Kempelen wrote:
Example 2:

Code: Select all

        eval&#91;color&#93; += somecode&#91;xturno&#93;
        eval&#91;color&#93; += somecode&#91;turno&#93;
        17 more operations of this kind
In the first example, for a pieze, only a condition is done, with 19 operations "normal" operations without using dimensional arrays
In the second one, no condition is executed, but 19 operations using var[color] type, whitch mean that at execution time, 2 add operations has to be done per line
Is appear to me that example 2 is more time consuming.....
No, Look at the code I posted.
Your function is inlined, there is no call to a function, all occurence of 'color' is replaced by a constant, the compiler will optimize the code and there will be no run-time overhead.

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

Re: Special code for black and white

Post by Kempelen »

Hi, Robert,

wooouh..... I modify my code yesterday, as my eval func is not so big, and avoiding code for white and black and making a generic routine for both colors, make the the eval function a 40% less eficcient. I measure the difference with the same 10 positions at the same fixed depth.!!!
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Special code for black and white

Post by bob »

Kempelen wrote:Hi, Robert,

wooouh..... I modify my code yesterday, as my eval func is not so big, and avoiding code for white and black and making a generic routine for both colors, make the the eval function a 40% less eficcient. I measure the difference with the same 10 positions at the same fixed depth.!!!
I did this in the crafty version 22.0 and carefully compared to version 21.x (whatever was current at the time) to make sure the scores matched exactly. When I was done, version 22.0 was very slightly faster, most likely a result of a significantly reduced cache footprint which offset the slightly slower array accesses...

You can probably compare crafty 22.0 and the last 21.x to see what I mean...

BTW you are not using "local data" correct? that would be a performance killer. You need to make this kind of data either global or static so that it is not constantly re-initialized each time that procedure is called...