about pst
Moderators: hgm, Rebel, chrisw
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: about pst
Don't understand what's simple about piece square table. Once I wrote code to update piece square tables and it became a mess soon. But perhaps evaluation cannot be written simple.
-
- Posts: 759
- Joined: Fri Jan 04, 2013 4:55 pm
- Location: Nice
Re: about pst
Thanks hg very clever !hgm wrote:In my new engine Simple I even store the eg and op values in the same table (pst[7][64]) of 32-bit integers, as (op-eg/3)*N + eg, where N is the constant 2^16. I have a game phase that runs from 0 (eg) to 24 (op). In the evaluation I then calculate (8*N+gamePhase)*pstEval>>19. Some algebra shows that this is equal to
({N*N*8*(op-eg)/3} + N*(gamePhase*(op-eg)/3 + 8*eg) + gamePhase*eg) >> 19
The part in braces contains a factor 2^32, and is thus clipped off the 32-bit result by overflow. Shifting right by 16 bits pushes the term gamePhase*eg (which is smaller than 2^16, eg running only upto 4000 or so even if the piece ase value is included in the PST) out of the int, and undoes the multiplication by N on the remaining term, so that it would leave you with
gamePhase/3 * (op-eg) + 8*eg
(give or take some rounding), where gamePhase/3 runs from 0 to 8 (so let us call that 8*phi). The result is then
8*(phi*op + (1-phi)*eg)
which is 8 times the sought interpolated result. Currently the factor 8 is also removed by right-shifting 3 bits extra (19 instead of 16), but it occurred to me that this is really counterproductive, and that it would be better to let the engine use units of 1/800 or 1/400 Pawn internally than have it use centiPawn. Then I can more easily reduce drawish positions (like KNKP) to sub-Pawn values by dividing the score by 2, 4 or 8 without completely losing the smaller evaluation terms like centralization to rounding, so that the engine will continue to prefer good moves in the hope for an opponent mistake, rather than throwing in the towel and running his King towards a corner to sulk, because it no longer sees the corner is worse than the center.
The evaluation parameters other than the PST (like isolated-Pawn penalty, open-file bonus for Rooks) are also defined in this (op-eg)/2*N+eg format, so that I can add them all to the pstEval value first, and then use the formula above for interpolating to the current game phase.
You're full again of ideas this year ... for normal chess but
Too high level for me and I would looove some explanations in french !😉
Bests
Dany
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: about pst
They are essentially equivalent. Speed-wise. etc.Daniel Anulliero wrote:Is it better (or not) to have :
What implementation is better in your advice ?Code: Select all
pst_op [7][64] = {.....} pst_eg [7][64] One array for all pièces Or pst_pawn_op [64] pst_knight_op [64] ... pst_knight_eg [64] ... Etc.. One array for each pièces (white , find the black values with a flip [64] array just like in TSCP code)
If you have a separate procedure for evaluating each distinct type of piece, which most do to collect related things in one place, a simple array works. Crafty uses things like pval[phase][square], nval[phase][square] and so forth. Adding a piece subscript won't make it less efficient since the piece type is known where it is used. If you use just one pst score array (pst[phase][piece][square] for example) then the piece will add a multiply/add to the subscript calculation when the compiler turns it into asm. I doubt you will be able to measure that speed loss.
In these cases, I try to use that which is most readable. Since I have procedures named EvaluatePawns(), EvaluateKnights() and such, I have a different PST array for each piece type. One less subscript makes it easier to read for me.
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: about pst
No, you missed the square problem. You have to convert e4 to the equivalent black square (e5) to use a simple one dimensional PST, rather than having one for black and one for white. Flipping a square through an array reference is going to add cache misses since it will be done in between lots of other code being executed.matthewlai wrote:Don't quite follow that. It's not XOR vs table look-up.sje wrote:It is faster to flip a square index by an inline exclusive-or calculation than by a table look-up.
It's XOR + table look-up vs table-lookup. Obviously not doing the XOR is faster.
My knight pst looks like this:
const int nval[EG/MG][btm/wtm][square] which is 2x2x64
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: about pst
Are you sure? 16/32/64K bytes of L1d is not very big when you factor in all the magic move generation references, hashing, board references and such. Has a better chance of sticking in L2, and almost always shold be in L3..matthewlai wrote:That is true. However, tables this size take up negligible L1D cache, and will stay there regardless.Aleks Peshkov wrote:It is not so obvious. Bigger table potentially lead to more cache misses. But XOR may be completely free in many cases due computational parallelism in modern processors.matthewlai wrote:It's XOR + table look-up vs table-lookup. Obviously not doing the XOR is faster.
-
- Posts: 4675
- Joined: Mon Mar 13, 2006 7:43 pm
Flipping squares
Code: Select all
flipsq = Flip[sq];
Code: Select all
flipsq = sq ^ 0x38;
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: Flipping squares
For those that use 0-63 of course.sje wrote:is slower thanCode: Select all
flipsq = Flip[sq];
Code: Select all
flipsq = sq ^ 0x38;
There are still a few mailboxers around.
-
- Posts: 931
- Joined: Tue Mar 09, 2010 3:46 pm
- Location: New York
- Full name: Álvaro Begué (RuyDos)
Re: Flipping squares
It's `sq ^ 0x70' for mailboxers.bob wrote:For those that use 0-63 of course.sje wrote:is slower thanCode: Select all
flipsq = Flip[sq];
Code: Select all
flipsq = sq ^ 0x38;
There are still a few mailboxers around.
-
- Posts: 931
- Joined: Tue Mar 09, 2010 3:46 pm
- Location: New York
- Full name: Álvaro Begué (RuyDos)
Re: Flipping squares
Oh, I meant for 0x88ers. By the way 0-63ers could use 070, which is somewhat more readable.AlvaroBegue wrote: It's `sq ^ 0x70' for mailboxers.
-
- Posts: 759
- Joined: Fri Jan 04, 2013 4:55 pm
- Location: Nice
Re: Flipping squares
not for me lolbob wrote:For those that use 0-63 of course.sje wrote:is slower thanCode: Select all
flipsq = Flip[sq];
Code: Select all
flipsq = sq ^ 0x38;
There are still a few mailboxers around.
Flip[sq] is 200ms faster than sq ^0x38 ...
don't understand why lol