Skip to content

Commit

Permalink
Re-added inlinings and added SkipLocalsInit (liamt19#60)
Browse files Browse the repository at this point in the history
bench: 4697595
  • Loading branch information
liamt19 authored Aug 15, 2024
1 parent 5bf5cda commit 9819518
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 43 deletions.
2 changes: 2 additions & 0 deletions Logic/Core/Bitboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public ulong BlockingPieces(int pc, ulong* pinners)
/// Returns a ulong with bits set at the positions of any piece that can attack the square <paramref name="idx"/>,
/// given the board occupancy <paramref name="occupied"/>.
/// </summary>
[MethodImpl(Inline)]
public ulong AttackersTo(int idx, ulong occupied)
{
return (GetBishopMoves(occupied, idx) & (Pieces[Bishop] | Pieces[Queen]))
Expand All @@ -216,6 +217,7 @@ public ulong AttackersTo(int idx, ulong occupied)
/// Returns a mask of the squares that a piece of type <paramref name="pt"/> and color <paramref name="pc"/>
/// on the square <paramref name="idx"/> attacks, given the board occupancy <paramref name="occupied"/>
/// </summary>
[MethodImpl(Inline)]
public ulong AttackMask(int idx, int pc, int pt, ulong occupied)
{
return pt switch
Expand Down
13 changes: 12 additions & 1 deletion Logic/Core/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ public void UnmakeNullMove()
/// Moves the king and rook for castle moves, and updates the position hash accordingly.
/// Adapted from https://github.com/official-stockfish/Stockfish/blob/632f1c21cd271e7c4c242fdafa328a55ec63b9cb/src/position.cpp#L931
/// </summary>
[MethodImpl(Inline)]
public void DoCastling(int ourColor, int from, int to, bool undo = false)
{
bool kingSide = to > from;
Expand Down Expand Up @@ -506,6 +507,7 @@ public void DoCastling(int ourColor, int from, int to, bool undo = false)



[MethodImpl(Inline)]
public void SetState()
{
State->Checkers = bb.AttackersTo(State->KingSquares[ToMove], bb.Occupancy) & bb.Colors[Not(ToMove)];
Expand All @@ -516,6 +518,7 @@ public void SetState()
}


[MethodImpl(Inline)]
public void SetCheckInfo()
{
State->BlockingPieces[White] = bb.BlockingPieces(White, &State->Pinners[Black]);
Expand Down Expand Up @@ -587,6 +590,7 @@ public ulong HashAfter(Move m)
/// Returns true if the move <paramref name="move"/> is pseudo-legal.
/// Only determines if there is a piece at move.From and the piece at move.To isn't the same color.
/// </summary>
[MethodImpl(Inline)]
public bool IsPseudoLegal(in Move move)
{
int moveTo = move.To;
Expand Down Expand Up @@ -646,11 +650,13 @@ public bool IsPseudoLegal(in Move move)
/// <summary>
/// Returns true if the move <paramref name="move"/> is legal in the current position.
/// </summary>
[MethodImpl(Inline)]
public bool IsLegal(in Move move) => IsLegal(move, State->KingSquares[ToMove], State->KingSquares[Not(ToMove)], State->BlockingPieces[ToMove]);

/// <summary>
/// Returns true if the move <paramref name="move"/> is legal given the current position.
/// </summary>
[MethodImpl(Inline)]
public bool IsLegal(Move move, int ourKing, int theirKing, ulong pinnedPieces)
{
int moveFrom = move.From;
Expand Down Expand Up @@ -763,7 +769,7 @@ public bool IsLegal(Move move, int ourKing, int theirKing, ulong pinnedPieces)




[MethodImpl(Inline)]
public bool IsDraw()
{
return IsFiftyMoveDraw() || IsInsufficientMaterial() || IsThreefoldRepetition();
Expand Down Expand Up @@ -842,6 +848,7 @@ public bool IsFiftyMoveDraw()
/// Returns the <see cref="CastlingStatus"/> for the piece on the <paramref name="sq"/>,
/// which is <see cref="CastlingStatus.None"/> if the square isn't one of the values in <see cref="CastlingRookSquares"/>.
/// </summary>
[MethodImpl(Inline)]
private CastlingStatus GetCastlingForRook(int sq)
{
CastlingStatus cr = sq == CastlingRookSquares[(int)CastlingStatus.WQ] ? CastlingStatus.WQ :
Expand All @@ -856,6 +863,7 @@ private CastlingStatus GetCastlingForRook(int sq)
/// <summary>
/// Updates the hash to reflect the changes in castling rights, and removes the given rights from the current state.
/// </summary>
[MethodImpl(Inline)]
private void RemoveCastling(CastlingStatus cr)
{
State->Hash.ZobristCastle(State->CastleStatus, cr);
Expand All @@ -867,6 +875,7 @@ private void RemoveCastling(CastlingStatus cr)
/// Returns the number of leaf nodes in the current position up to <paramref name="depth"/>.
/// </summary>
/// <param name="depth">The number of moves that will be made from the starting position. Depth 1 returns the current number of legal moves.</param>
[SkipLocalsInit]
public ulong Perft(int depth)
{
ScoredMove* list = stackalloc ScoredMove[MoveListSize];
Expand All @@ -890,6 +899,7 @@ public ulong Perft(int depth)

private Stopwatch PerftTimer = new Stopwatch();
private const int PerftParallelMinDepth = 6;
[SkipLocalsInit]
public ulong PerftParallel(int depth, bool isRoot = false)
{
if (isRoot)
Expand Down Expand Up @@ -934,6 +944,7 @@ public ulong PerftParallel(int depth, bool isRoot = false)
/// Same as perft but returns the evaluation at each of the leaves.
/// Only for benchmarking/debugging.
/// </summary>
[SkipLocalsInit]
public long PerftNN(int depth)
{
ScoredMove* list = stackalloc ScoredMove[MoveListSize];
Expand Down
2 changes: 2 additions & 0 deletions Logic/Data/Move.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ public override string ToString()
/// <summary>
/// Returns true if the <see cref="Move"/> <paramref name="move"/> has the same From/To squares, the same "Castle" flag, and the same PromotionTo piece.
/// </summary>
[MethodImpl(Inline)]
public bool Equals(Move move)
{
// Today we learned that the JIT doesn't appear to create separate paths for Equals(object) and Equals(Move/CondensedMove).
Expand All @@ -224,6 +225,7 @@ public bool Equals(Move move)



[MethodImpl(Inline)]
public bool Equals(ScoredMove move)
{
return move.Move.Equals(this);
Expand Down
5 changes: 4 additions & 1 deletion Logic/Data/RootMove.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Lizard.Logic.Data
using System.Runtime.CompilerServices;

namespace Lizard.Logic.Data
{
public class RootMove : IComparable<RootMove>
{
Expand All @@ -25,6 +27,7 @@ public RootMove(Move move, int score = -ScoreInfinite)
PVLength = 1;
}

[MethodImpl(Inline)]
public int CompareTo(RootMove other)
{
if (Score != other.Score)
Expand Down
26 changes: 19 additions & 7 deletions Logic/Magic/MagicBitboards.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Runtime.InteropServices;

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;

namespace Lizard.Logic.Magic
Expand Down Expand Up @@ -85,22 +87,30 @@ static MagicBitboards()
for (int m = 0; m < 100; m++)
foreach ((int sq, ulong blockers) in pextTests)
temp ^= TestPextFancy(blockers, sq);
if (n > 0) fancyElapsed += sw.ElapsedTicks;

sw.Stop();
if (n > 0)
fancyElapsed += sw.ElapsedTicks;
sw.Restart();
for (int m = 0; m < 100; m++)
foreach ((int sq, ulong blockers) in pextTests)
temp ^= TestPextNormal(blockers, sq);
if (n > 0) normalElapsed += sw.ElapsedTicks;

sw.Restart();
for (int m = 0; m < 100; m++)
foreach ((int sq, ulong blockers) in pextTests)
temp ^= TestPextFancy(blockers, sq);
if (n > 0) fancyElapsed += sw.ElapsedTicks;

sw.Restart();
for (int m = 0; m < 100; m++)
foreach ((int sq, ulong blockers) in pextTests)
temp ^= TestPextNormal(blockers, sq);
sw.Stop();
if (n > 0)
normalElapsed += sw.ElapsedTicks;
if (n > 0) normalElapsed += sw.ElapsedTicks;
}

UsePext = (fancyElapsed < normalElapsed);

if (UsePext) Log($"Pext enabled for a {normalElapsed / (double)fancyElapsed:N3}x speedup");
}

if (UsePext)
Expand Down Expand Up @@ -136,6 +146,7 @@ static MagicBitboards()
/// and the returned mask treats the mask <paramref name="boardAll"/> as if every piece can be captured.
/// Friendly pieces will need to be masked out so we aren't able to capture them.
/// </summary>
[MethodImpl(Inline)]
public static ulong GetRookMoves(ulong boardAll, int idx)
{
if (UsePext)
Expand All @@ -157,6 +168,7 @@ public static ulong GetRookMoves(ulong boardAll, int idx)
/// and the returned mask treats the mask <paramref name="boardAll"/> as if every piece can be captured.
/// Friendly pieces will need to be masked out so we aren't able to capture them.
/// </summary>
[MethodImpl(Inline)]
public static ulong GetBishopMoves(ulong boardAll, int idx)
{
if (UsePext)
Expand Down
5 changes: 4 additions & 1 deletion Logic/NN/Accumulator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;

namespace Lizard.Logic.NN
Expand Down Expand Up @@ -28,6 +29,7 @@ public Accumulator()

public Vector256<short>* this[int perspective] => (perspective == Color.White) ? (Vector256<short>*)White : (Vector256<short>*)Black;

[MethodImpl(Inline)]
public void CopyTo(Accumulator* target)
{
Unsafe.CopyBlock(target->White, White, ByteSize);
Expand All @@ -38,6 +40,7 @@ public void CopyTo(Accumulator* target)

}

[MethodImpl(Inline)]
public void CopyTo(ref Accumulator target, int perspective)
{
Unsafe.CopyBlock(target[perspective], this[perspective], ByteSize);
Expand Down
6 changes: 6 additions & 0 deletions Logic/NN/Bucketed768.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;

using Lizard.Logic.Threads;
Expand Down Expand Up @@ -268,6 +269,7 @@ public static int GetEvaluation(Position pos)
return (output / QA + LayerBiases[outputBucket]) * OutputScale / (QA * QB);
}

[MethodImpl(Inline)]
private static int FeatureIndexSingle(int pc, int pt, int sq, int kingSq, int perspective)
{
const int ColorStride = 64 * 6;
Expand All @@ -288,6 +290,7 @@ private static int FeatureIndexSingle(int pc, int pt, int sq, int kingSq, int pe
return ((768 * KingBuckets[kingSq]) + ((pc ^ perspective) * ColorStride) + (pt * PieceStride) + (sq)) * HiddenSize;
}

[MethodImpl(Inline)]
private static (int, int) FeatureIndex(int pc, int pt, int sq, int wk, int bk)
{
const int ColorStride = 64 * 6;
Expand Down Expand Up @@ -408,6 +411,7 @@ public static void MakeMove(Position pos, Move m)
}
}

[MethodImpl(Inline)]
public static void MakeNullMove(Position pos)
{
pos.State->Accumulator->CopyTo(pos.NextState->Accumulator);
Expand All @@ -421,6 +425,7 @@ public static void MakeNullMove(Position pos)

// The general concept here is based off of Stormphrax's implementation:
// https://github.com/Ciekce/Stormphrax/commit/9b76f2a35531513239ed7078acc21294a11e75c6
[MethodImpl(Inline)]
public static void ProcessUpdates(Position pos)
{
StateInfo* st = pos.State;
Expand Down Expand Up @@ -462,6 +467,7 @@ public static void ProcessUpdates(Position pos)
}
}

[MethodImpl(Inline)]
public static void UpdateSingle(Accumulator* prev, Accumulator* curr, int perspective)
{
ref var updates = ref curr->Update[perspective];
Expand Down
5 changes: 4 additions & 1 deletion Logic/Search/Searches.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text;
using System.Runtime.CompilerServices;
using System.Text;

using Lizard.Logic.NN;
using Lizard.Logic.Search.History;
Expand Down Expand Up @@ -50,6 +51,7 @@ public static void HandleNewGame()
/// The depth to search to, which is then extended by QSearch.
/// </param>
/// <returns>The evaluation of the best move.</returns>
[SkipLocalsInit]
public static int Negamax<NodeType>(Position pos, SearchStackEntry* ss, int alpha, int beta, int depth, bool cutNode) where NodeType : SearchNodeType
{
bool isRoot = typeof(NodeType) == typeof(RootNode);
Expand Down Expand Up @@ -714,6 +716,7 @@ public static int Negamax<NodeType>(Position pos, SearchStackEntry* ss, int alph
/// This is similar to Negamax, but there is far less pruning going on here, and we are only interested in ensuring that
/// the score for a particular Negamax node is reasonable if we look at the forcing moves that can be made after that node.
/// </summary>
[SkipLocalsInit]
public static int QSearch<NodeType>(Position pos, SearchStackEntry* ss, int alpha, int beta, int depth) where NodeType : SearchNodeType
{
bool isPV = typeof(NodeType) != typeof(NonPVNode);
Expand Down
47 changes: 15 additions & 32 deletions Logic/Transposition/TTEntry.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

using static Lizard.Logic.Transposition.TranspositionTable;

Expand Down Expand Up @@ -40,7 +41,7 @@ public struct TTEntry
public readonly TTNodeType NodeType => (TTNodeType)(_AgePVType & TT_BOUND_MASK);
public readonly int Bound => _AgePVType & TT_BOUND_MASK;


[MethodImpl(Inline)]
public readonly sbyte RelAge(byte age) => (sbyte)((TT_AGE_CYCLE + age - _AgePVType) & TT_AGE_MASK);
public readonly bool IsEmpty => _Depth == 0;

Expand Down Expand Up @@ -73,22 +74,13 @@ public void Update(ulong key, short score, TTNodeType nodeType, int depth, Move
/// </summary>
public static short MakeNormalScore(short ttScore, int ply)
{
if (ttScore == ScoreNone)
return ttScore switch
{
return ttScore;
}

if (ttScore >= ScoreTTWin)
{
return (short)(ttScore - ply);
}

if (ttScore <= ScoreTTLoss)
{
return (short)(ttScore + ply);
}

return ttScore;
ScoreNone => ttScore,
>= ScoreTTWin => (short)(ttScore - ply),
<= ScoreTTLoss => (short)(ttScore + ply),
_ => ttScore
};
}

/// <summary>
Expand All @@ -100,22 +92,13 @@ public static short MakeNormalScore(short ttScore, int ply)
/// </summary>
public static short MakeTTScore(short score, int ply)
{
if (score == ScoreNone)
return score switch
{
return score;
}

if (score >= ScoreTTWin)
{
return (short)(score + ply);
}

if (score <= ScoreTTLoss)
{
return (short)(score - ply);
}

return score;
ScoreNone => score,
>= ScoreTTWin => (short)(score + ply),
<= ScoreTTLoss => (short)(score - ply),
_ => score
};
}

public override string ToString()
Expand Down
Loading

0 comments on commit 9819518

Please sign in to comment.