HLSf use nuint rather than long, L4 now uses hlsf rather than array to alloc cache line.

This commit is contained in:
Youmu Liu
2026-04-20 18:10:14 +08:00
parent 1b7c929be4
commit 2e2d64a2ce
38 changed files with 796 additions and 465 deletions
@@ -60,7 +60,7 @@ namespace StgSharp.HighPerformance.Memory
{
ref CacheLinePrediction handle = ref span[i];
nuint address = handle.Address;
if (!TestHit(address))
if (!_map.TryGet(address, out _))
{
// miss and record
span[missIndex] = handle;
@@ -88,19 +88,21 @@ namespace StgSharp.HighPerformance.Memory
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 (predict.IsSamePolicy(head->_profile, belong))
{
head->_predictor =predictIndex;
head->_predictor = (short)predictIndex;
} else
{
// Compatibility failed, so the old owner must first flush its view of
// the line before the new predictor rematerializes the cache bytes.
belong.WriteBack(head->_origin, head->_profile, new ReadOnlySpan<byte>((byte*)head->_address, Unsafe.SizeOf<CacheLineData>()));
belong.WriteBack(head->_origin, head->_profile, new ReadOnlySpan<byte>((byte*)head->_address, head->_size));
head->_profile = pHandle.MapPolicy;
predict.Prefetch(head->_origin, head->_profile, new Span<byte>((byte*)head->_address, Unsafe.SizeOf<CacheLineData>()));
predict.Prefetch(head->_origin, head->_profile, new Span<byte>((byte*)head->_address, head->_size));
}
#endregion
@@ -110,7 +112,8 @@ namespace StgSharp.HighPerformance.Memory
int retryCount = 0, remain = missIndex - i;
const int maxRetry = 1024;
while (!TryGetEmptyLine(out index))
HlsfHandle hlsfHandle;
while (!TryGetEmptyLine(pHandle.Size, out index, out hlsfHandle))
{
remain = Evict(remain);
retryCount++;
@@ -126,11 +129,12 @@ namespace StgSharp.HighPerformance.Memory
head->_origin = address;
head->_profile = pHandle.MapPolicy;
head->_refCount = 0;
head->_predictor = predictIndex;
head->_address = (nuint)(_data + index);
head->_predictor = (short)predictIndex;
head->_address = (nuint)hlsfHandle.Pointer;
head->_size = pHandle.Size;
// pre fetch them here
predict.Prefetch(head->_origin, head->_profile, new Span<byte>((byte*)head->_address, Unsafe.SizeOf<CacheLineData>()));
predict.Prefetch(head->_origin, head->_profile, new Span<byte>((byte*)head->_address, (int)head->_size));
_ = _map.TryAddOrSet(address, (nuint)head, out _);
}
_ = Interlocked.Add(ref _aheadCount, actualCount);