L4 is now on new algo, using new eviction arrays, using union of hlsf and cache line head.

This commit is contained in:
Youmu Liu
2026-04-23 17:39:38 +08:00
parent 5252be9436
commit 1a6ce24a27
5 changed files with 117 additions and 97 deletions
@@ -25,6 +25,7 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -44,15 +45,12 @@ namespace StgSharp.HighPerformance.Memory
static IIntrinsicKernel Instance { get; } = Create();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AgeAll(
EvictionArray* eviction
);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ScanEvict(
byte* vPtr,
Vector128<byte> three
short* pPtr,
short* mPtr,
int count,
L4 owner
);
private static IIntrinsicKernel Create()
@@ -68,35 +66,49 @@ namespace StgSharp.HighPerformance.Memory
}
private struct SseKernel : IIntrinsicKernel
private readonly struct SseKernel : IIntrinsicKernel
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AgeAll(
EvictionArray* eviction
public readonly int ScanEvict(
short* pPtr,
short* mPtr,
int count,
L4 owner
)
{
Vector128<byte> one = Vector128.Create((byte)0x01);
Vector128<byte> max = Vector128.Create((byte)0x03);
byte* p = (byte*)eviction;
for (int i = 0; i < CacheLineCount; i += 16)
int remain = count;
ConcurrentFlexibleArray<IL4Predict> predictors = owner._predictors;
predictors.RequestSpanOperation();
Span<IL4Predict> pSpan = predictors.AsSpan();
try
{
Vector128<byte> v = Sse2.LoadVector128(p + i);
v = Sse2.AddSaturate(v, one);
v = Sse2.Min(v, max);
Sse2.Store(p + i, v);
}
}
for (int i = 0; i < CacheLineCount; i += 8)
{
Vector128<short> p = Sse2.LoadVector128(pPtr + i);
Vector128<short> m = Sse2.LoadVector128(mPtr + i);
Vector128<short> great = Sse2.CompareGreaterThan(p, m);
Vector128<short> le = Sse42.Xor(great, Vector128.Create<short>(-1));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ScanEvict(
byte* vPtr,
Vector128<byte> three
)
{
Vector128<byte> v = Sse2.LoadVector128(vPtr);
Vector128<byte> mask = Sse2.CompareEqual(v, three);
return Sse2.MoveMask(mask);
int mask = Sse42.MoveMask(le.AsByte());
while ((mask != 0) && (remain > 0))
{
int bit = BitOperations.TrailingZeroCount(mask);
int lane = bit >> 1;
if (owner.TryEvictAt(i + lane, pSpan)) {
remain--;
}
mask &= mask - 1;
mask &= mask - 1;
}
}
}
finally
{
predictors.ReleaseSpanOperation();
}
return remain;
}
}