Skip to content

Commit

Permalink
Memory optimization stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
WorkingRobot committed Nov 12, 2023
1 parent 23a2293 commit 4b1fe02
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 36 deletions.
4 changes: 2 additions & 2 deletions Simulator/Actions/ActionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public enum ActionType : byte

public static class ActionUtils
{
private static readonly BaseAction[] Actions;
private static ReadOnlyMemory<BaseAction> Actions { get; }

static ActionUtils()
{
Expand All @@ -61,7 +61,7 @@ static ActionUtils()

[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static BaseAction Base(this ActionType me) => Actions[(int)me];
public static BaseAction Base(this ActionType me) => Actions.Span[(int)me];

public static IEnumerable<ActionType> AvailableActions(Simulator simulation) =>
simulation.IsComplete
Expand Down
11 changes: 1 addition & 10 deletions Simulator/SimulationState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public record struct SimulationState
public ActionStates ActionStates;

// https://github.com/ffxiv-teamcraft/simulator/blob/0682dfa76043ff4ccb38832c184d046ceaff0733/src/model/tables.ts#L2
private static readonly int[] HQPercentTable = {
private static ReadOnlySpan<int> HQPercentTable => new[] {
1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8,
9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 17, 17,
17, 18, 18, 18, 19, 19, 20, 20, 21, 22, 23, 24, 26, 28, 31, 34, 38, 42, 47, 52, 58, 64, 68, 71,
Expand All @@ -44,13 +44,4 @@ public SimulationState(SimulationInput input)
ActionCount = 0;
ActionStates = new();
}

#if IS_DETERMINISTIC
public override readonly string ToString()
{
var b = new System.Text.StringBuilder();
PrintMembers(b);
return Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(b.ToString())));
}
#endif
}
12 changes: 6 additions & 6 deletions Solver/MCTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ private static (int arrayIdx, int subIdx) ChildMaxScore(in NodeScoresBuffer scor
{
var iterCount = Math.Min(vecLength, length);

ref var chunk = ref scores.Data[i];
var m = new Vector<float>(chunk.MaxScore.Span);
ref var chunk = ref scores.Data!.Value.Span[i];
var m = new Vector<float>(chunk.MaxScore);

var idx = Intrinsics.HMaxIndex(m, iterCount);

Expand Down Expand Up @@ -127,10 +127,10 @@ private static (int arrayIdx, int subIdx) EvalBestChild(
{
var iterCount = Math.Min(vecLength, length);

ref var chunk = ref scores.Data[i];
var s = new Vector<float>(chunk.ScoreSum.Span);
var vInt = new Vector<int>(chunk.Visits.Span);
var m = new Vector<float>(chunk.MaxScore.Span);
ref var chunk = ref scores.Data!.Value.Span[i];
var s = new Vector<float>(chunk.ScoreSum);
var vInt = new Vector<int>(chunk.Visits);
var m = new Vector<float>(chunk.MaxScore);

vInt = Vector.Max(vInt, Vector<int>.One);
var v = Vector.ConvertToSingle(vInt);
Expand Down
40 changes: 22 additions & 18 deletions Solver/NodeScoresBuffer.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Craftimizer.Solver;

// Adapted from https://github.com/dtao/ConcurrentList/blob/4fcf1c76e93021a41af5abb2d61a63caeba2adad/ConcurrentList/ConcurrentList.cs
public struct NodeScoresBuffer
{
public sealed class ScoresBatch
public readonly struct ScoresBatch
{
public Memory<float> ScoreSum;
public Memory<float> MaxScore;
public Memory<int> Visits;

public ScoresBatch()
{
ScoreSum = new float[BatchSize];
MaxScore = new float[BatchSize];
Visits = new int[BatchSize];
}
private readonly Memory<byte> data;

public Span<float> ScoreSum =>
MemoryMarshal.Cast<byte, float>(data.Span.Slice(0, BatchSize * sizeof(float)));
public Span<float> MaxScore =>
MemoryMarshal.Cast<byte, float>(data.Span.Slice(BatchSize * sizeof(float), BatchSize * sizeof(float)));
public Span<int> Visits =>
MemoryMarshal.Cast<byte, int>(data.Span.Slice(BatchSize * sizeof(float) * 2, BatchSize * sizeof(int)));

public ScoresBatch() =>
data = new byte[BatchSize * sizeof(float) * 3];
}

// Technically 25, but it's very unlikely to actually get to there.
Expand All @@ -31,7 +33,7 @@ public ScoresBatch()

private static readonly int BatchCount = MaxSize / BatchSize;

public ScoresBatch[] Data;
public Memory<ScoresBatch>? Data;
public int Count { get; private set; }

public void Add()
Expand All @@ -40,20 +42,22 @@ public void Add()

var idx = Count++;

var (arrayIdx, _) = GetArrayIndex(idx);
var (arrayIdx, subIdx) = GetArrayIndex(idx);

Data[arrayIdx] ??= new();
if (subIdx == 0)
Data.Value.Span[arrayIdx] = new();
}

public readonly void Visit((int arrayIdx, int subIdx) at, float score)
{
Data[at.arrayIdx].ScoreSum.Span[at.subIdx] += score;
Data[at.arrayIdx].MaxScore.Span[at.subIdx] = Math.Max(Data[at.arrayIdx].MaxScore.Span[at.subIdx], score);
Data[at.arrayIdx].Visits.Span[at.subIdx]++;
ref var batch = ref Data!.Value.Span[at.arrayIdx];
batch.ScoreSum[at.subIdx] += score;
batch.MaxScore[at.subIdx] = Math.Max(batch.MaxScore[at.subIdx], score);
batch.Visits[at.subIdx]++;
}

public readonly int GetVisits((int arrayIdx, int subIdx) at) =>
Data[at.arrayIdx].Visits.Span[at.subIdx];
Data!.Value.Span[at.arrayIdx].Visits[at.subIdx];

[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down

1 comment on commit 4b1fe02

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 4b1fe02 Previous: 3edb156 Ratio
Craftimizer.Benchmark.Bench.Solve(State: 5372D31C98FA4C357F54029912394B0F5ECBE94AEC9D12C1C2B7F453C62ACD2F, Config: B75845A5DEDC79F3C98FE35F28206855B0EF4E065555FAF2AA129AED115B7744) 1609691320 ns (± 5024691.819860341)
Craftimizer.Benchmark.Bench.Solve(State: 5372D31C98FA4C357F54029912394B0F5ECBE94AEC9D12C1C2B7F453C62ACD2F, Config: B75845A5DEDC79F3C98FE35F28206855B0EF4E065555FAF2AA129AED115B7744) 1006993920 ns (± 5874146.218472945)
Craftimizer.Benchmark.Bench.Solve(State: 99B0F1AD46A18B4D8262F9BA75ABE23507217C2F20FBF895A49282DDFEF50190, Config: B75845A5DEDC79F3C98FE35F28206855B0EF4E065555FAF2AA129AED115B7744) 1786471546.6666667 ns (± 9958608.851990944)
Craftimizer.Benchmark.Bench.Solve(State: 99B0F1AD46A18B4D8262F9BA75ABE23507217C2F20FBF895A49282DDFEF50190, Config: B75845A5DEDC79F3C98FE35F28206855B0EF4E065555FAF2AA129AED115B7744) 1100198246.6666667 ns (± 4287497.439210675)

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.