Another how can you lose example.
O wait Fairy max searching much deeper. If depth means anything.
[pgn]
[Event "Computer Chess Game"]
[Site "LAPTOP-1FK7MTIP"]
[Date "2021.05.03"]
[Round "-"]
[White "Skipper_8_10"]
[Black "Fairy-Max 4.8V"]
[Result "0-1"]
[TimeControl "180"]
[Annotator "1. +0.45 3... +0.25"]
1. e4 {+0.45/7} e5 2. Nc3 {+0.04/6 4} Nf6 3. f4 {+0.52/7 3} exf4
{+0.25/9 2.9} 4. e5 {+0.85/7 3} Ng8 {+0.59/9 10} 5. Nf3 {+0.51/6 3} g5
{+0.75/8 7} 6. d4 {+0.42/6 3} g4 {+1.14/8 3} 7. Ng1 {+0.45/7 3} Qh4+
{+0.42/8 2.3} 8. Ke2 {+0.25/7 3} g3 {+0.25/8 2.1} 9. Nf3 {+0.92/7 3} Qh6
{+0.09/9 2.2} 10. Nd5 {+0.73/5 3} Qa6+ {+0.08/8 4} 11. Qd3 {+0.95/6 3} Qc6
{+0.07/9 5} 12. Nxf4 {+0.67/6 2.9} b6 {-0.08/8 4} 13. d5 {+1.43/6 2.9} Qa4
{-0.64/9 5} 14. b3 {+1.48/5 2.8} Qa6 {-0.76/9 2.3} 15. hxg3 {+1.33/7 2.8}
Qxd3+ {-0.72/8 6} 16. cxd3 {+1.37/7 2.7} Ne7 {-0.62/8 4} 17. Bb2
{+1.89/6 2.6} Rg8 {-0.84/8 2.9} 18. Rxh7 {+2.31/5 2.6} Nf5 {-0.70/10 4} 19.
Nh5 {+2.42/5 2.6} Nxg3+ {-0.82/10 2.7} 20. Nxg3 {+2.27/7 2.5} Rxg3
{-1.01/10 2.2} 21. Kf2 {+2.42/6 2.5} Rg8 {-0.74/9 4} 22. Nd2 {+1.93/5 2.4}
Bc5+ {-0.79/8 2.4} 23. d4 {+2.39/7 2.4} Be7 {-0.98/10 2.6} 24. Bd3
{+2.34/5 2.3} d6 {-0.76/7 1.6} 25. Nc4 {+2.29/5 2.3} Nd7 {-0.63/8 2.1} 26.
exd6 {+2.22/5 2.2} cxd6 {-0.95/9 1.4} 27. Rh6 {+2.24/6 2.2} Nf6
{-1.28/9 2.4} 28. Nxd6+ {+2.49/6 2.1} Kf8 {-1.23/8 1.5} 29. Nxc8
{+2.76/5 2.1} Rxc8 {-1.13/9 1.8} 30. Rh3 {+2.63/5 2.1} Rd8 {-1.11/8 1.2}
31. Bc1 {+2.96/5 2.0} Ng4+ {-0.94/9 1.7} 32. Kf3 {+2.49/7 2.0} Rxd5
{-1.51/9 1.7} 33. Bh7 {+2.15/7 1.9} Rg7 {-1.59/10 1.6} 34. Bb2
{+2.25/6 1.9} f5 {-0.93/9 1.5} 35. Bc3 {+2.08/5 1.9} Nf6 {+0.92/9 1.1} 36.
Rah1 {+0.14/6 1.8} Ne4 {+0.94/9 1.1} 37. Bb2 {+0.13/5 1.8} Ng5+
{+0.85/8 1.0} 38. Kf2 {-0.18/8 1.7} Nxh3+ {+0.64/9 1.5} 39. Rxh3
{-0.22/7 1.7} Rg4 {+0.77/8 1.1} 40. Rf3 {-0.13/6 1.7} Bh4+ {+0.71/9 1.3}
41. Kf1 {+0.42/7 1.7} f4 {+0.50/10 2.1} 42. Be4 {+0.74/7 1.6} Ra5
{+0.66/10 2.5} 43. a4 {+0.74/7 1.6} Bf6 {+0.56/9 1.4} 44. Bc3 {+0.46/6 1.6}
Rh5 {+0.69/9 1.8} 45. Kg1 {+0.59/6 1.5} Rgh4 {+0.81/9 1.0} 46. b4
{+0.78/7 1.5} Rh1+ {+0.84/9 1.3} 47. Kf2 {+0.94/7 1.5} Bh4+ {+0.72/10 2.0}
48. Ke2 {+0.88/7 1.4} Bg3 {+0.60/10 2.2} 49. d5 {+1.04/6 1.4} Rh6
{+0.48/9 2.4} 50. Be5 {+1.26/6 1.4} Re1+ {+0.58/8 0.9} 51. Kd3
{+1.34/6 1.4} Ke7 {+0.52/9 6} 52. b5 {+1.45/5 1.3} Rh4 {+0.68/8 1.2} 53.
d6+ {+1.79/6 1.3} Ke6 {+1.07/8 0.7} 54. Kd4 {+0.61/5 1.3} Rd1+
{+1.41/9 0.8} 55. Bd3 {-0.92/8 1.3} Bh2 {+1.36/9 0.7} 56. d7 {-0.35/7 1.3}
Kxd7 {+1.45/8 0.9} 57. Rh3 {-0.31/6 1.2} Rxh3 {+2.49/9 0.6} 58. gxh3
{-1.07/8 1.2} Bg1+ {+2.74/12 0.7} 59. Kc3 {-2.74/7 1.2} f3 {+2.75/11 0.7}
60. Kc2 {-3.09/6 1.1} Re1 {+3.20/12 1.0} 61. Bb8 {-3.25/6 1.1} Kc8
{+3.50/13 1.6} 62. Bg3 {-4.04/6 1.1} f2 {+3.85/13 0.8} 63. h4 {-3.73/6 1.1}
f1=Q {+4.46/13 0.7} 64. Bxf1 {-4.47/8 1.1} Rxf1 {+4.46/12 5} 65. Kb2
{-4.15/6 1.0} Bh2 {+4.49/9 0.5} 66. Bxh2 {-5.22/7 1.0} Rf2+ {+4.52/11 0.7}
67. Kc3 {-5.68/8 1.0} Rxh2 {+4.63/11 0.6} 68. h5 {-5.80/7 1.0} Rxh5
{+4.74/11 0.6} 69. Kb2 {-5.79/7 1.0} Rh4 {+5.85/12 1.3} 70. Kb3
{-5.86/7 0.9} Kc7 {+5.96/12 1.2} 71. Ka3 {-6.37/7 0.9} Kd6 {+5.95/12 1.1}
72. Kb2 {-7.75/7 0.9} Rxa4 {+5.95/11 0.9} 73. Kb3 {-7.80/7 0.9} Ra5
{+6.04/12 0.4} 74. Kc4 {-7.87/8 0.9} Ke5 {+6.22/12 0.7} 75. Kb4
{-8.74/8 0.9} Kd4 {+13.69/13 0.7} 76. Kb3 {-8.73/8 0.8} Rxb5+
{+13.71/13 0.8} 77. Ka4 {-9.56/7 0.8} Rb2 {+79.96/17 0.4} 78. Ka3
{-327.60/8 0.8} Kc3 {+79.97/28 0.2} 79. Ka4 {-327.62/8 0.8} Rb1
{+79.98/28 0.2} 80. Ka3 {-327.64/8 0.8} Ra1# {+79.99/28 0.2}
{Xboard adjudication: Checkmate} 0-1
[/pgn]
Complicating code in C#
Moderators: hgm, Rebel, chrisw
-
- Posts: 3
- Joined: Thu May 06, 2021 3:57 am
- Full name: Max Bennedich
Re: Complicating code in C#
Do you have the full code posted somewhere? I'm happy to take a look. I wrote an engine in Java some time ago and spent some time optimizing it, many of the tricks I did should apply to C# too. One thing I can recommend, if you want to improve performance, is to not do any allocations at all in your time sensitive code. (Basically avoid using the `new` operator.) Instead preallocate and reuse all objects and arrays.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
No I don't have the code posted somewhere.
Already have a problem with DoMove for it makes a copy of a position.
That would mean I have to preallocate millions of positions ?
But I will try to reduce allocations.
Maybe also remove virtual methods.
Last days busy with removing ChessPosition objects for all data is stored in ChessBoard (objects) now.
Currently a ChessPosition object still contains one ChessBoard object . Very much work to rewrite the code for zillions of ChessPosition references in my code right now.
Terrible.
Already have a problem with DoMove for it makes a copy of a position.
That would mean I have to preallocate millions of positions ?
But I will try to reduce allocations.
Maybe also remove virtual methods.
Last days busy with removing ChessPosition objects for all data is stored in ChessBoard (objects) now.
Currently a ChessPosition object still contains one ChessBoard object . Very much work to rewrite the code for zillions of ChessPosition references in my code right now.
Terrible.
-
- Posts: 1784
- Joined: Wed Jul 03, 2019 4:42 pm
- Location: Netherlands
- Full name: Marcel Vanthoor
Re: Complicating code in C#
No, you allocate one board, and then make and unmake your move on that board.
I've seen posts about these problems at least 5 years back. I still wonder why you don't just start over with what you know now, avoid the mistakes you made earlier, and be done with it.Last days busy with removing ChessPosition objects for all data is stored in ChessBoard (objects) now.
Currently a ChessPosition object still contains one ChessBoard object . Very much work to rewrite the code for zillions of ChessPosition references in my code right now.
Terrible.
-
- Posts: 3
- Joined: Thu May 06, 2021 3:57 am
- Full name: Max Bennedich
Re: Complicating code in C#
As mentioned above, it'd be enough with just a single instance, and do the moves and then (after the recursive call) unmove on that same instance.
As an implementation detail, I copy the state before I do the move, and perform the unmove by simply copying it back. But importantly, I do this without repeated allocations -- I just pre-allocate one board per ply (e.g. 63 instances) to keep the copies.
-
- Posts: 3
- Joined: Thu May 06, 2021 3:57 am
- Full name: Max Bennedich
Re: Complicating code in C#
Virtual methods suggest to me that you're using some inheritance model? Yes, I'd stay away from that in your time sensitive code, as it might slow things down and prevent the compiler from doing certain optimizations. Efficient code in Java and C# is unfortunately not always very idiomatic...
With that said, whenever you do changes that sacrifice readability and flexibility, I'd make sure to benchmark that you're indeed getting a decent performance gain out of it, or it's not worth it.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
The reason I started to make copies was because I thought it would be easier to implement multi threading later.
But if it makes your code already three times slower ...
Best start by making code multi threaded. Then you know which objects should be immutable.
But if it makes your code already three times slower ...
Best start by making code multi threaded. Then you know which objects should be immutable.
-
- Posts: 95
- Joined: Fri Nov 09, 2012 12:36 am
Re: Complicating code in C#
multi thread is easy when you start with it in mind
my c# engine does multi thread without issue, nothing special in it, no oriented object no inheritance nothing complex
not even transposition table or hash (like zobrist)
single thread look like this
multi thread look like this
my c# engine does multi thread without issue, nothing special in it, no oriented object no inheritance nothing complex
not even transposition table or hash (like zobrist)
single thread look like this
Code: Select all
A B C D E F G H
1 R ■ ■ Q ■ R K ■ Kind of perft: Full Perft, doing all move/undo to the last depth
2 P p ■ P ■ ■ P P Started 6 depths at 2021-05-06 23:33:56 finished at 2021-05-06 23:34:31
3 q ■ ■ ■ ■ N ■ ■ FEN: r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1
4 B B P ■ P ■ ■ ■
5 n P ■ ■ ■ ■ ■ ■ Expected Moves : 706,045,033
6 ■ b ■ ■ ■ n b N Total Moves Done : 706,045,033
7 P p p p ■ p p p Time Taken : 34,856ms
8 r ■ ■ ■ k ■ ■ r Moves per second : 20,256,054
Code: Select all
A B C D E F G H
1 R ■ ■ Q ■ R K ■ Kind of perft: Full Perft, doing all move/undo to the last depth
2 P p ■ P ■ ■ P P Started 6 depths at 2021-05-06 23:35:32 finished at 2021-05-06 23:35:35
3 q ■ ■ ■ ■ N ■ ■ FEN: r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1
4 B B P ■ P ■ ■ ■
5 n P ■ ■ ■ ■ ■ ■ Expected Moves : 706,045,033
6 ■ b ■ ■ ■ n b N Total Moves Done : 706,045,033
7 P p p p ■ p p p Time Taken : 2,527ms
8 r ■ ■ ■ k ■ ■ r Moves per second : 279,400,487
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
I now have quiescence search alloc free.
Schwindel game below. See ending.
[pgn]
[Event "Computer Chess Game"]
[Site "LAPTOP-1FK7MTIP"]
[Date "2021.05.13"]
[Round "-"]
[White "Skipper_8_13"]
[Black "Fairy-Max 4.8V"]
[Result "1/2-1/2"]
[TimeControl "180"]
[Annotator "1. +0.18 5... -0.04"]
1. e4 {+0.18/9} c5 2. Nf3 {+0.00/8 4} d6 3. Nc3 {+0.26/9 3} Nf6 4. Bc4
{+0.19/8 3} Nc6 5. d3 {+0.26/8 3} g6 {-0.04/8 11} 6. Nd5 {+0.60/8 3} Bg7
{+0.03/8 3} 7. Bg5 {+0.55/7 3} O-O {+0.26/8 4} 8. Nxf6+ {+0.17/7 3} exf6
{-0.05/8 2.9} 9. Bf4 {+0.19/8 3} Ne5 {+0.12/7 3} 10. Bd5 {+0.16/9 3} Qb6
{+0.04/7 4} 11. O-O {+0.73/8 3} Qxb2 {+0.74/8 4} 12. Rb1 {+0.56/8 2.9} Qa3
{+0.74/8 5} 13. Rb3 {+0.95/6 2.9} Qa5 {+0.74/8 3} 14. Bxb7 {+0.38/7 2.8}
Bxb7 {+0.75/10 3} 15. Rxb7 {+0.10/8 2.8} Qxa2 {+0.75/9 3} 16. c4
{+0.12/7 2.7} h6 {+0.78/8 2.6} 17. Be3 {-0.05/7 2.7} Qa3 {+0.76/8 2.2} 18.
Nxe5 {+0.03/8 2.6} fxe5 {+0.80/9 1.9} 19. f4 {-0.21/8 2.6} Qa6
{+0.81/9 2.8} 20. Rb5 {-0.31/8 2.5} exf4 {+0.82/10 2.5} 21. Rxf4
{-0.42/9 2.5} Be5 {+0.80/10 6} 22. Rf3 {-0.31/8 2.4} h5 {+0.70/9 2.2} 23.
d4 {-0.27/8 2.4} cxd4 {+0.70/10 1.7} 24. Bxd4 {-0.35/8 2.3} Bxd4+
{+0.73/10 2.0} 25. Qxd4 {-0.17/7 2.3} Rab8 {+0.74/10 2.3} 26. Rfb3
{+0.48/8 2.2} Rxb5 {+0.74/11 1.6} 27. cxb5 {+0.23/8 2.2} Qb6 {+0.79/10 2.2}
28. Qxb6 {+0.27/11 2.1} axb6 {+0.80/14 2.5} 29. Rd3 {-0.72/10 2.1} Rd8
{+0.70/13 4} 30. h4 {-0.70/10 2.0} f6 {+0.89/14 1.9} 31. Kh2 {-0.80/9 2.0}
Kf7 {+0.91/14 1.3} 32. Kg3 {-0.66/9 2.0} Ke6 {+0.91/14 3} 33. Kf4
{-0.75/10 1.9} Rc8 {+0.91/13 1.4} 34. g4 {-0.80/10 1.9} hxg4 {+1.50/13 1.2}
35. Kxg4 {-1.84/10 1.9} Rc4 {+1.47/14 2.8} 36. Kh3 {-1.81/9 1.8} Rxe4
{+1.59/14 1.1} 37. Rg3 {-3.04/9 1.8} Rb4 {+1.60/15 2.0} 38. Re3+
{-3.16/10 1.8} Kf7 {+1.62/16 1.8} 39. Rd3 {-3.11/11 1.7} d5 {+1.68/16 1.3}
40. Rxd5 {-2.77/10 1.7} Ke6 {+1.49/15 1.3} 41. Rd3 {-2.81/10 1.7} Rxb5
{+1.45/15 1.0} 42. Rg3 {-3.18/10 1.6} Kf5 {+1.47/15 1.4} 43. Rf3+
{-2.66/10 1.6} Ke5 {+0.78/16 1.6} 44. Re3+ {-2.51/11 1.6} Kf4
{+1.46/15 1.5} 45. Rg3 {-2.45/11 1.5} g5 {+1.46/16 1.3} 46. Rg4+
{-2.66/11 1.5} Kf3 {+1.45/16 1.4} 47. Rg3+ {-2.53/11 1.5} Ke4
{+1.45/15 1.2} 48. h5 {-1.95/10 1.4} Rb1 {+1.43/14 1.7} 49. Kh2
{-2.84/9 1.4} Rb2+ {+1.38/13 1.2} 50. Kh3 {-2.41/10 1.4} Kf4 {+1.47/15 1.4}
51. h6 {-1.66/10 1.4} f5 {+1.44/15 0.9} 52. Rxg5 {+0.00/12 1.3} Kxg5
{+3.91/18 0.9} 53. h7 {+0.00/12 1.3} Rb3+ {+3.90/16 1.7} 54. Kg2
{+0.00/10 1.3} Rb2+ {+0.01/15 1.9} 55. Kh3 {+0.00/11 1.3} Rb1
{+0.01/14 0.8} 56. Kg2 {+0.00/9 1.3} Rb2+ {+0.00/15 0.8} 57. Kh3
{+0.00/11 1.2}
{XBoard adjudication: repetition draw} 1/2-1/2
[/pgn]
Schwindel game below. See ending.
[pgn]
[Event "Computer Chess Game"]
[Site "LAPTOP-1FK7MTIP"]
[Date "2021.05.13"]
[Round "-"]
[White "Skipper_8_13"]
[Black "Fairy-Max 4.8V"]
[Result "1/2-1/2"]
[TimeControl "180"]
[Annotator "1. +0.18 5... -0.04"]
1. e4 {+0.18/9} c5 2. Nf3 {+0.00/8 4} d6 3. Nc3 {+0.26/9 3} Nf6 4. Bc4
{+0.19/8 3} Nc6 5. d3 {+0.26/8 3} g6 {-0.04/8 11} 6. Nd5 {+0.60/8 3} Bg7
{+0.03/8 3} 7. Bg5 {+0.55/7 3} O-O {+0.26/8 4} 8. Nxf6+ {+0.17/7 3} exf6
{-0.05/8 2.9} 9. Bf4 {+0.19/8 3} Ne5 {+0.12/7 3} 10. Bd5 {+0.16/9 3} Qb6
{+0.04/7 4} 11. O-O {+0.73/8 3} Qxb2 {+0.74/8 4} 12. Rb1 {+0.56/8 2.9} Qa3
{+0.74/8 5} 13. Rb3 {+0.95/6 2.9} Qa5 {+0.74/8 3} 14. Bxb7 {+0.38/7 2.8}
Bxb7 {+0.75/10 3} 15. Rxb7 {+0.10/8 2.8} Qxa2 {+0.75/9 3} 16. c4
{+0.12/7 2.7} h6 {+0.78/8 2.6} 17. Be3 {-0.05/7 2.7} Qa3 {+0.76/8 2.2} 18.
Nxe5 {+0.03/8 2.6} fxe5 {+0.80/9 1.9} 19. f4 {-0.21/8 2.6} Qa6
{+0.81/9 2.8} 20. Rb5 {-0.31/8 2.5} exf4 {+0.82/10 2.5} 21. Rxf4
{-0.42/9 2.5} Be5 {+0.80/10 6} 22. Rf3 {-0.31/8 2.4} h5 {+0.70/9 2.2} 23.
d4 {-0.27/8 2.4} cxd4 {+0.70/10 1.7} 24. Bxd4 {-0.35/8 2.3} Bxd4+
{+0.73/10 2.0} 25. Qxd4 {-0.17/7 2.3} Rab8 {+0.74/10 2.3} 26. Rfb3
{+0.48/8 2.2} Rxb5 {+0.74/11 1.6} 27. cxb5 {+0.23/8 2.2} Qb6 {+0.79/10 2.2}
28. Qxb6 {+0.27/11 2.1} axb6 {+0.80/14 2.5} 29. Rd3 {-0.72/10 2.1} Rd8
{+0.70/13 4} 30. h4 {-0.70/10 2.0} f6 {+0.89/14 1.9} 31. Kh2 {-0.80/9 2.0}
Kf7 {+0.91/14 1.3} 32. Kg3 {-0.66/9 2.0} Ke6 {+0.91/14 3} 33. Kf4
{-0.75/10 1.9} Rc8 {+0.91/13 1.4} 34. g4 {-0.80/10 1.9} hxg4 {+1.50/13 1.2}
35. Kxg4 {-1.84/10 1.9} Rc4 {+1.47/14 2.8} 36. Kh3 {-1.81/9 1.8} Rxe4
{+1.59/14 1.1} 37. Rg3 {-3.04/9 1.8} Rb4 {+1.60/15 2.0} 38. Re3+
{-3.16/10 1.8} Kf7 {+1.62/16 1.8} 39. Rd3 {-3.11/11 1.7} d5 {+1.68/16 1.3}
40. Rxd5 {-2.77/10 1.7} Ke6 {+1.49/15 1.3} 41. Rd3 {-2.81/10 1.7} Rxb5
{+1.45/15 1.0} 42. Rg3 {-3.18/10 1.6} Kf5 {+1.47/15 1.4} 43. Rf3+
{-2.66/10 1.6} Ke5 {+0.78/16 1.6} 44. Re3+ {-2.51/11 1.6} Kf4
{+1.46/15 1.5} 45. Rg3 {-2.45/11 1.5} g5 {+1.46/16 1.3} 46. Rg4+
{-2.66/11 1.5} Kf3 {+1.45/16 1.4} 47. Rg3+ {-2.53/11 1.5} Ke4
{+1.45/15 1.2} 48. h5 {-1.95/10 1.4} Rb1 {+1.43/14 1.7} 49. Kh2
{-2.84/9 1.4} Rb2+ {+1.38/13 1.2} 50. Kh3 {-2.41/10 1.4} Kf4 {+1.47/15 1.4}
51. h6 {-1.66/10 1.4} f5 {+1.44/15 0.9} 52. Rxg5 {+0.00/12 1.3} Kxg5
{+3.91/18 0.9} 53. h7 {+0.00/12 1.3} Rb3+ {+3.90/16 1.7} 54. Kg2
{+0.00/10 1.3} Rb2+ {+0.01/15 1.9} 55. Kh3 {+0.00/11 1.3} Rb1
{+0.01/14 0.8} 56. Kg2 {+0.00/9 1.3} Rb2+ {+0.00/15 0.8} 57. Kh3
{+0.00/11 1.2}
{XBoard adjudication: repetition draw} 1/2-1/2
[/pgn]
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Cleared remainder of search as well. That is no unnecessary allocs, allocate everything in advance and re-use them.
But performance does not get better than 350kn/sec on my machine while Stockfish easily makes 1 million nodes per second.
Might be because of single threading.
By the way code getting more instable and tricky now due to last changes. Maybe I introduced some hidden errors as well.
But performance does not get better than 350kn/sec on my machine while Stockfish easily makes 1 million nodes per second.
Might be because of single threading.
By the way code getting more instable and tricky now due to last changes. Maybe I introduced some hidden errors as well.