add multi predictor support to l4, working for ver 5 of mat parallel

This commit is contained in:
Youmu Liu
2026-04-09 18:07:49 +08:00
parent 0bad6bb480
commit f7187ca7fd
19 changed files with 653 additions and 187 deletions
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="L4.Predict"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,8 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Common.Collections;
using StgSharp.Mathematics.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -33,85 +35,65 @@ using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
[Flags]
public enum PredictResult
public partial class L4
{
Success = 1,
Exhausted = 2,
private ConcurrentBufferStack<int> _idReuse = new(32);
}
private ConcurrentFlexibleArray<IL4Predict> _predictions = new(32);
public interface IL4Predict
{
private int _largestId = 0;
PredictResult Predict(Span<CacheLinePrediction> node, out int count);
private Queue<int> _predictionQueue = [];
/// <summary>
/// Materializes the cache line identified by <paramref name="origin" /> into <paramref /// ///
/// name="cache" />.
/// </summary>
/// <param name="origin">
/// Source address associated with the cache line.
/// </param>
/// <param name="policy">
/// Mapping policy associated with the cache line.
/// </param>
/// <param name="cache">
/// Destination cache line buffer.
/// </param>
void Prefetch(nuint origin, ulong policy, Span<byte> cache);
private IL4Predict CurrentPredict { get; set; }
/// <summary>
/// Writes the cache line in <paramref name="cache" /> back to <paramref name="origin" />.
/// </summary>
/// <param name="origin">
/// Source address associated with the cache line.
/// </param>
/// <param name="policy">
/// Mapping policy associated with the cache line.
/// </param>
/// <param name="cache">
/// Source cache line buffer.
/// </param>
void WriteBack(nuint origin, ulong policy, ReadOnlySpan<byte> cache);
}
public struct CacheLinePrediction : IEquatable<CacheLinePrediction>
{
public override readonly bool Equals(object? obj)
public int RegisterPredict(
IL4Predict predict
)
{
return (obj is CacheLinePrediction prediction) &&
Address.Equals(prediction.Address) &&
(MapPolicy == prediction.MapPolicy);
if (predict is null) {
return -1;
}
if (!_idReuse.TryPop(out int id)) {
id = _largestId++;
}
_predictions[id] = predict;
_predictionQueue.Enqueue(id);
return id;
}
public readonly bool Equals(CacheLinePrediction other)
public IL4Predict? UnregisterPredict(
int id
)
{
return
(Address == other.Address) && (MapPolicy == other.MapPolicy);
if (id < 0) {
return null;
}
IL4Predict p = _predictions[id];
if (p == null) {
return p;
}
_predictions[id] = null!;
// TODO: scan and write back
_idReuse.Push(id);
return p;
}
public override readonly int GetHashCode()
private void UseNewPredict()
{
return HashCode.Combine(Address, MapPolicy);
if (_predictionQueue.Count == 0) {
return;
}
if (_predictionQueue.TryDequeue(out int id))
{
IL4Predict predict = _predictions[id] ??
throw new L4PredictUnregisteredException(id);
CurrentPredict = predict;
}
}
public static bool operator !=(CacheLinePrediction left, CacheLinePrediction right)
{
return !(left == right);
}
public static bool operator ==(CacheLinePrediction left, CacheLinePrediction right)
{
return left.Equals(right);
}
#pragma warning disable CA1051
public nuint Address;
public ulong MapPolicy;
#pragma warning restore CA1051
}
}