ajaja.....Harald Johnsen wrote: Now, look again the assembler output, no index.
HJ.
I see the point now. The trick is the 'inline' keyword!
Moderator: Ras
ajaja.....Harald Johnsen wrote: Now, look again the assembler output, no index.
HJ.
There actually are not "many variables". There are a few but the count is no more than a couple of dozen. Things like which square does a white/black sit on if it castles king-side, something like OO[2] = {G1, G8}; And the like... Squares or ranks were the only issue I had to deal with (rook on 7th for example, etc). Scores and such exist as just one value, where to compute the score for knights, I do this:PK-4 wrote:I am a little surprised. I thought the burden of indexing many variables with piece colour would cause a slowdown. But I would not argue with observation and try this sometime.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...
I don't think so, I chose to make them all global constants since they are never modified, and that assigns them values at compile time once and for all.So the compiler inserts initilisation code for local variables - is it possible to prevent this with some compiler switch rather than "static" at so many places?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...
Regards
I think the point he misses is that any reference like pawn_square[0] or pawn_square[1] does no array reference calculations at all, those are simply two memory variables with no subscript. When you inline, all the black/white indices become simple memory references with no penalty other than the memory access which was already there.Harald Johnsen wrote:Your compiler can output the assembler listing of the source.PK-4 wrote: I am a little surprised. I thought the burden of indexing many variables with piece colour would cause a slowdown. But I would not argue with observation and try this sometime.
Oh and I repeat it, there is *no* indexing with the piece color. The compiler generates the code for the white and for the black side. There is no color indexing.
No. The compiler does not insert anything. There is no initialization code if your variable is not an object. Even int i = 2; is a no-op.So the compiler inserts initilisation code for local variables - is it possible to prevent this with some compiler switch rather than "static" at so many places?
Regards
If you suspect compiler bad job then you can add a const modifier on all constant, add a no pointer aliasing modifier where needed. But don't do manual 'optimization' that are counter productive.
HJ.
You are overlooking the key point. We are doing something likeKempelen wrote:I think you are confusing...... There is indexing. The compiler can never know what color a pieze has in a square sq. That is information dynamically generated as game runs. Can the compiler know that square c2 has a black bishop in a game agains Crafty?Harald Johnsen wrote: Your compiler can output the assembler listing of the source.
Oh and I repeat it, there is *no* indexing with the piece color. The compiler generates the code for the white and for the black side. There is no color indexing.
.....
HJ.
(also I saw the assambly code and indexes was needed).
You can see a more complete code I have posted in a reply to Bob in this thread, you will see that indexes are needed.
Unless you do inlining, then things change significantly as the arrays turn into constant values in the inlined code.PK-4 wrote:My apologies for misreading 'data' as 'variable' - hurry is the surest performance killer. Of course local data would be initialised at every call.PK-4 wrote:So the compiler inserts initilisation code for local variables - is it possible to prevent this with some compiler switch rather than "static" at so many places?Bob wrote:
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...
Do you compile everything as one large source file, so that the compiler can inline this stuff? If you put the calling procedure in one file, and the called procedure in a separate file, and compile independently, then no inlining and there could be any degree of performance penalty...Kempelen wrote:No Dann, there is no bug, because I get the same result in testing both versions. (evaluating 10 differents positions).Dann Corbit wrote: The speed change should be insignificant. You introduced a bug, I think.
You generally don't even need to worry about that as the compiler will do it automagically, so long as you compile everything together so that it can see the caller and callee when compiling. Otherwise you have to tell it (Intel at least) that you want inter-file optimizations...Kempelen wrote:ajaja.....Harald Johnsen wrote: Now, look again the assembler output, no index.
HJ.
I see the point now. The trick is the 'inline' keyword!
Code: Select all
// Pawn captures left (square mapping H8=bit 0, H7=bit 1,... A1=bit 63)
Atk = ((Pieces[BPAWNS + wtm]&~FILE_A1A8)<<(9-(wtm<<1)));
Atk &= Pieces[ALLBPIECES + !wtm]; // may use !wtm == wtm^1
This works neatly for captures because your board is sidewise to what I'm used to, but how do you do it for non-captures, as you need to shift in different directions?Lasse Hansen wrote:Hi!
I use wtm as an index and have arranged most data sets to fit this,
so that [white pieces] are addressed as the [black pieces + 1], (wtm 0 or 1).
Here is an example of making both white and black pawn captures with same code.It might seem dirty to use logical not in indices, but it's readableCode: Select all
// Pawn captures left (square mapping H8=bit 0, H7=bit 1,... A1=bit 63) Atk = ((Pieces[BPAWNS + wtm]&~FILE_A1A8)<<(9-(wtm<<1))); Atk &= Pieces[ALLBPIECES + !wtm]; // may use !wtm == wtm^1
to me (and I did not see any difference when trying wtm^1).
Regards, Lasse
Code: Select all
// White + Black : Double pawn step
B = Pieces[BPAWNS + wtm] & (RANK_A7H7 << 5*wtm);
B = ((B>>1)<<(2-(wtm<<1))) & ~(Pieces[ALLBPIECES] | Pieces[ALLWPIECES]);
Atk = ((B>>1)<<(2-(wtm<<1))) & ~(Pieces[ALLBPIECES] | Pieces[ALLWPIECES]);
// White + Black : Normal 1-step moves
Atk = ((Pieces[BPAWNS + wtm]>>1)<<(2-(wtm<<1))) & ~(Pieces[ALLBPIECES] | Pieces[ALLWPIECES]);