add multi predictor support to l4, working for ver 5 of mat parallel
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user