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
@@ -26,6 +26,7 @@
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System.ComponentModel;
using System.Numerics;
namespace StgSharp.HighPerformance.Memory
{
@@ -55,7 +56,6 @@ namespace StgSharp.HighPerformance.Memory
return;
}
int missIndex = 0;
AgeAll();
for (int i = 0; i < actualCount; i++)
{
ref CacheLineDescription handle = ref span[i];
@@ -82,26 +82,40 @@ namespace StgSharp.HighPerformance.Memory
{
head = (CacheLineHead*)handle;
index = head->Id;
(*_eviction)[index] = 0; // reset eviction counter
(*_predictCount)[index] = 0; // reset eviction counter
#region update predictor belonging
int predictId = head->Predictor;
IL4Predict belong = predictorSpan[predictId];
// TODO 由于L4的缓存行改为“可变长度”缓存行,需要调整缓存行复用策略
// This branch performs resident-line adoption rather than a simple policy
// equality check. Returning true means the current predictor can keep using
// the existing cache bytes without a write-back plus re-prefetch cycle.
if (!ReferenceEquals(predict, belong))
{
throw new L4PredictConflictException(head->Origin, head->Profile, predictId);
} else
{
// Compatibility failed, so the old owner must first flush its view of
// the line before the new predictor rematerializes the cache bytes.
_ = Interlocked.Increment(ref head->RemainingPredictionCount);
if ((*_predictCount)[index] > short.MaxValue / 2)
{
/*
* EXPERIMENTAL / INTENTIONALLY UNSAFE:
* This code performs a 32-bit atomic operation starting from a short reference.
*
* It is only valid in this specific storage layout because:
* - the runtime is little-endian;
* - arithmetic here does not cause harmful cross-16-bit carry/borrow;
* - the backing storage remains valid and accessible beyond the logical short-array boundary;
* - touching the adjacent 16 bits is acceptable for this allocation layout;
* - misaligned int access is acceptable on the target platform.
*
* This is safe only with the current L4 allocation/layout guarantees.
*/
short predictCount = Volatile.Read(ref (*_predictCount)[index]);
short mapCount = Volatile.Read(ref (*_mapCount)[index]);
int decrement = (short.Min(predictCount, mapCount) + 1) / 2;
_ = Interlocked.Add(ref Unsafe.As<short, int>(ref (*_predictCount)[index]), -decrement);
_ = Interlocked.Add(ref Unsafe.As<short, int>(ref (*_mapCount)[index]), -decrement);
}
(*_predictCount)[index]++;
}
#endregion
@@ -122,8 +136,8 @@ namespace StgSharp.HighPerformance.Memory
Thread.Sleep(1);
}
}
head = &_head[index];
head->_id = index;
head = _head + index;
head->Id = index;
head->Origin = address;
head->Profile = pHandle.MapPolicy;
head->RefCount = 0;