spirch wrote: ↑Mon Sep 27, 2021 5:31 pm
mutable struct is something that you should avoid at all cost (cases where you want this should have a very good reason), that is why a class is more appropriate in c#.
I don't know what mutability has to do with our goal to make the C# code faster?
There are plenty of examples of mutable structs in the .Net Framework or Unity Game engine. Yes, I don't argue against the fact that there are few good reasons to design your structs in a way where they are immutable but that's got nothing to do with performance. If anything this has the potential to hurt the performance.
In our specific case of the TMove struct it would neither help nor hurt the performance as far as I can see but it would mean we cant use initializers anymore and then we need a constructor and in essence we have just written a bunch of extra code and gained nothing tangible for it.
Your conclusion to turn every mutable struct either into a class or encode the fields in integral value types via bitfiddling has no justification in my opinion. You make a class when you want a reference type and you make it a struct when you want a value type. That's the only important characteristic in our performance-critical use case.
And my general rule of thumb with this project so far was to change the code where necessary to help the stupid C# compiler with reaching the C compilers performances. But when there's no problem there's no need for a fix.
Minimal Chess (simple, open source, C#) - Youtube & Github Leorik (competitive, in active development, C#) - Github & Lichess
lithander wrote: ↑Mon Sep 27, 2021 12:36 pm
I've looked into the modifications made by spirch and I'm not sure how you all feel about his changes away from the TMove struct to encoding all move properties in an int instead and using constants instead of the TPieceType enum?
IMO that's fine, if it helps performance. I did that already in the Java version.
[Moderation warning] This signature violated the rule against commercial exhortations.
R. Tomasi wrote: ↑Mon Sep 27, 2021 11:47 am
I'm back home now, so that I can use my developement machine where I can run more accurate tests than on the laptop where I have no control over thermal throttling. It's a 10th gen. Intel i9 with a custom watercooling loop. That allows me to fix the clock speed and the CPU itself also will almost never trigger any thermal throttling. I will run a comparision of the windows and linux version to get exact figures. Linux version will run against WSL, though, but I'm rather confident it will behave like a pure linux system, since it is the same ubuntu kernel.
Welcome back. In my experience, on the same hardware, WSL was about 10% slower than pure Ubuntu for a very CPU/memory intensive workload. YMMV.
[Moderation warning] This signature violated the rule against commercial exhortations.
R. Tomasi wrote: ↑Mon Sep 27, 2021 7:48 pm
It is possible to store a move in chess with 16bits only. I would however not go down that road in our example, since that changes the underlying algorithm imho.
IMHO this would be perfectly fine since it seems like an implementation detail, not algorithmic. It just seems like a pointless change, since the move already fits in 32 bits, and there will likely be a slight performance hit from that bit fiddling. Did you find that it helped, Spirch?
Also IMHO, it's about time to do a few more optimizations that one would do in an actual chess engine, like PEXT bitboards to speed up the rook and bishop generation, and multithreading. I think that would help set the languages apart. As far as I know you can't do PEXT in Java for example.
[Moderation warning] This signature violated the rule against commercial exhortations.
R. Tomasi wrote: ↑Mon Sep 27, 2021 11:47 am
I'm back home now, so that I can use my developement machine where I can run more accurate tests than on the laptop where I have no control over thermal throttling. It's a 10th gen. Intel i9 with a custom watercooling loop. That allows me to fix the clock speed and the CPU itself also will almost never trigger any thermal throttling. I will run a comparision of the windows and linux version to get exact figures. Linux version will run against WSL, though, but I'm rather confident it will behave like a pure linux system, since it is the same ubuntu kernel.
Welcome back. In my experience, on the same hardware, WSL was about 10% slower than pure Ubuntu for a very CPU/memory intensive workload. YMMV.
Ok. Let's keep that in mind then, once I have done the measurements. I would think however, that this equally applies to the C and C# versions, such that the comparision with respect to that would still give the correct ratio.
klx wrote: ↑Mon Sep 27, 2021 11:18 pm
Also IMHO, it's about time to do a few more optimizations that one would do in an actual chess engine, like PEXT bitboards to speed up the rook and bishop generation, and multithreading. I think that would help set the languages apart.
In principle I'd be fine with that. I would however like to run a first round of tests without optimizations of that sort. Once lithander has the latest version up in the repo I'll do these.
klx wrote: ↑Mon Sep 27, 2021 11:18 pm
As far as I know you can't do PEXT in Java for example.
I won't be able to test the Java version: I do not have Java installed on my machine, and I outright refuse to do so
R. Tomasi wrote: ↑Mon Sep 27, 2021 7:48 pm
It is possible to store a move in chess with 16bits only. I would however not go down that road in our example, since that changes the underlying algorithm imho.
IMHO this would be perfectly fine since it seems like an implementation detail, not algorithmic. It just seems like a pointless change, since the move already fits in 32 bits, and there will likely be a slight performance hit from that bit fiddling. Did you find that it helped, Spirch?
It's a battle between the performance hit of the bit twiddling and the performance gain from needing half of the memory bandwidth. Personally, I would not want to bet on either of these to win.
R. Tomasi wrote: ↑Mon Sep 27, 2021 7:48 pm
It is possible to store a move in chess with 16bits only. I would however not go down that road in our example, since that changes the underlying algorithm imho.
IMHO this would be perfectly fine since it seems like an implementation detail, not algorithmic. It just seems like a pointless change, since the move already fits in 32 bits, and there will likely be a slight performance hit from that bit fiddling. Did you find that it helped, Spirch?
Also IMHO, it's about time to do a few more optimizations that one would do in an actual chess engine, like PEXT bitboards to speed up the rook and bishop generation, and multithreading. I think that would help set the languages apart. As far as I know you can't do PEXT in Java for example.
I personally prefer less memory and some bit twidding, than large memory bandwith.
you don't even need a struct for a move.
in my engine i encode the moves as 'ushort' data type. (unsigned 16 bit integer)
R. Tomasi wrote: ↑Mon Sep 27, 2021 7:48 pm
It is possible to store a move in chess with 16bits only. I would however not go down that road in our example, since that changes the underlying algorithm imho.
IMHO this would be perfectly fine since it seems like an implementation detail, not algorithmic. It just seems like a pointless change, since the move already fits in 32 bits, and there will likely be a slight performance hit from that bit fiddling. Did you find that it helped, Spirch?
Also IMHO, it's about time to do a few more optimizations that one would do in an actual chess engine, like PEXT bitboards to speed up the rook and bishop generation, and multithreading. I think that would help set the languages apart. As far as I know you can't do PEXT in Java for example.
I personally prefer less memory and some bit twidding, than large memory bandwith.
you don't even need a struct for a move.
in my engine i encode the moves as 'ushort' data type. (unsigned 16 bit integer)
Yeah. There's also the thing about less memory requirement of TT and killer entries, etc. I have a hunch that in the code that we're benchmarking the 32bit moves will be faster, since memory bandwidth probably isn't an issue. One might however argue, that what we're testing is not how fast we can make a perft in some language, but how the languages perform under a typical chess-engine workload. Compressing the moves into 16bit would imho be part of such a typical workload. I'm inclined to advocate for making the 16bit moves mandatory in all language versions that we test...
I pushed four commits and made dedicated releases for each of them so that each modification can be studied and benchmarked in isolation. The release notes contain my measurements.
klx wrote: ↑Mon Sep 27, 2021 11:18 pm
Also IMHO, it's about time to do a few more optimizations that one would do in an actual chess engine, like PEXT bitboards to speed up the rook and bishop generation, and multithreading. I think that would help set the languages apart. As far as I know you can't do PEXT in Java for example.
R. Tomasi wrote: ↑Tue Sep 28, 2021 12:13 am
I'm inclined to advocate for making the 16bit moves mandatory in all language versions that we test...
Feel free to fork the repo if you plan bigger changes!
Minimal Chess (simple, open source, C#) - Youtube & Github Leorik (competitive, in active development, C#) - Github & Lichess