Simplifying code II

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Henk
Posts: 7216
Joined: Mon May 27, 2013 10:31 am

Simplifying code II

Post by Henk »

Back to the start. By the way what terrible interface AlphaBetaSearch has here. Maybe add some more properties to memento.
Don't talk about efficiency. It will ruin my code for sure.

Code: Select all

 var memento = Board.CreateMoveMemento(mv);        
 Board.DoMove(mv);
 var researchVal = AlphaBetaSearch(out bestLine, null, -ub, -lb, depth - 1, plyCount + 1, nextPsqValue, check);
 int? val = researchVal.HasValue ? -researchVal.Value : null;
 Board.UndoMove(mv, memento);
 return val;
 
Last edited by Henk on Mon Sep 20, 2021 1:17 pm, edited 6 times in total.
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Simplifying code II

Post by R. Tomasi »

Just to be sure: that's C#?
Henk
Posts: 7216
Joined: Mon May 27, 2013 10:31 am

Re: Simplifying code II

Post by Henk »

R. Tomasi wrote: Mon Sep 20, 2021 1:08 pm Just to be sure: that's C#?
Yes C# or maybe C#.NET. I even don't know the difference.
User avatar
mvanthoor
Posts: 1784
Joined: Wed Jul 03, 2019 4:42 pm
Location: Netherlands
Full name: Marcel Vanthoor

Re: Simplifying code II

Post by mvanthoor »

Henk's been writing a chess engine for at least 10 years without knowing which programming language he's actually using... I think that's a first. It could also be the source of some mistakes here and there.
R. Tomasi wrote: Mon Sep 20, 2021 1:08 pm Just to be sure: that's C#?
Henk wrote: Mon Sep 20, 2021 1:12 pm Yes C# or maybe C#.NET. I even don't know the difference.
Author of Rustic, an engine written in Rust.
Releases | Code | Docs | Progress | CCRL
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Simplifying code II

Post by R. Tomasi »

Jokes aside, OPs quetion reminds me of something I've been wondering about a lot lately. For functions that inherently can't be inlined (like the recursive functions you would have in a recursive alpha-beta search implementation) and that have many arguments (which at least in my engine is the case for the search functions): does it help to pass the arguments by reference in a single struct? I'm inclined to think it should lower the register load, thereby giving the compiler more space to optimize the function. Anyone experimented with that? Doing tests in that direction is something on my todo-list, anyways...
BrokenKeyboard
Posts: 24
Joined: Tue Mar 16, 2021 11:11 pm
Full name: Het Satasiya

Re: Simplifying code II

Post by BrokenKeyboard »

It would probably be a lot more readable if you had a specific struct / type for the function input, yea! It would also reduce the confusion when you reference a parameter. It would be something like

Code: Select all

params.alpha
instead of just

Code: Select all

alpha
.
That could be a lot more readable and could increase performance.
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Simplifying code II

Post by R. Tomasi »

BrokenKeyboard wrote: Mon Sep 20, 2021 8:00 pm It would probably be a lot more readable if you had a specific struct / type for the function input, yea! It would also reduce the confusion when you reference a parameter. It would be something like

Code: Select all

params.alpha
instead of just

Code: Select all

alpha
.
That could be a lot more readable and could increase performance.
Just use a different name than params (that's a reserved word in C#).
pedrojdm2021
Posts: 157
Joined: Fri Apr 30, 2021 7:19 am
Full name: Pedro Duran

Re: Simplifying code II

Post by pedrojdm2021 »

Henk wrote: Mon Sep 20, 2021 1:05 pm Back to the start. By the way what terrible interface AlphaBetaSearch has here. Maybe add some more properties to memento.
Don't talk about efficiency. It will ruin my code for sure.

Code: Select all

 var memento = Board.CreateMoveMemento(mv);        
 Board.DoMove(mv);
 var researchVal = AlphaBetaSearch(out bestLine, null, -ub, -lb, depth - 1, plyCount + 1, nextPsqValue, check);
 int? val = researchVal.HasValue ? -researchVal.Value : null;
 Board.UndoMove(mv, memento);
 return val;
 
to avoid confutions in my code i usually name the parameters with a "_" before the name of the parameter.

for example:

Code: Select all

void foo(string _paramA, int _paramB)
{
 // amazing stuff here
}
you can also use "m_variableName" for local variables inside your class

these small tips can help :D
User avatar
mvanthoor
Posts: 1784
Joined: Wed Jul 03, 2019 4:42 pm
Location: Netherlands
Full name: Marcel Vanthoor

Re: Simplifying code II

Post by mvanthoor »

R. Tomasi wrote: Mon Sep 20, 2021 7:20 pm Jokes aside, OPs quetion reminds me of something I've been wondering about a lot lately. For functions that inherently can't be inlined (like the recursive functions you would have in a recursive alpha-beta search implementation) and that have many arguments (which at least in my engine is the case for the search functions): does it help to pass the arguments by reference in a single struct? I'm inclined to think it should lower the register load, thereby giving the compiler more space to optimize the function. Anyone experimented with that? Doing tests in that direction is something on my todo-list, anyways...
My alpha-beta function stores references to everything it needs in a struct called "refs", of the type "SearchRefs". Things in there are references to the board, the move generator, etc. If I would pass all those references one by one, the alpha-beta function would have a massive list of parameters.

So it should help if you pass only one reference to a struct containing either the stuff you need, or more references. The reason is that passing one reference (pointer) takes 8 bytes to copy. If you pass more references, you'll need to copy 8 bytes for each reference, so the function call becomes slower.
Author of Rustic, an engine written in Rust.
Releases | Code | Docs | Progress | CCRL
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Simplifying code II

Post by R. Tomasi »

mvanthoor wrote: Mon Sep 20, 2021 10:41 pm The reason is that passing one reference (pointer) takes 8 bytes to copy. If you pass more references, you'll need to copy 8 bytes for each reference, so the function call becomes slower.
Well, yes and no. Of course the size of a pointer is typically 8 or 4 bytes, depending on your hardware. But passing arguments to a function does usually not involve copying memory, since the first n arguments will be passed in registers. The exact value of n and which registers are used depend on the calling convention. Only when too many arguments are needed they will be passed via the stack. And I guess that's the catch: the registers used for passing parameters are in use and the compiler can't use them for local variables when it is optimizing the function. Most calling conventions are designed to balance between using registers for parameters and for local variables. But if you have less parameters, there is more room for the compiler to optimize. That last sentence is a hunch of mine - I'm not exactly sure how big the impact is. That's why I am asking if someone has experimented with that. The drawback of passing a pointer/reference to a struct, is that this struct will most certainly live on the stack, which means memory accesses will be involved and those may be slow. I would however suspect that the local stack is cached.