L4 completely add support for multi predictor, working on ver 5 mat para
This commit is contained in:
@@ -42,9 +42,13 @@ namespace StgSharp.HighPerformance.Memory
|
||||
if (_activeCount > MaxActivateCacheLineCount) {
|
||||
throw new OverflowException("Too many activated cache line in external reference.");
|
||||
}
|
||||
IL4Predict predict = CurrentPredict;
|
||||
Span<CacheLinePrediction> span = new(_prediction, PredictionCount);
|
||||
PredictResult result = PrefetchPredict.Predict(span, out int actualCount);
|
||||
if ((result == PredictResult.Exhausted) && (actualCount <= 0))
|
||||
PredictResult result = predict.Predict(span, out int actualCount);
|
||||
if ((result & PredictResult.Exhausted) != 0) {
|
||||
_exhausted = !TryGetNextPredict();
|
||||
}
|
||||
if (actualCount <= 0)
|
||||
{
|
||||
_exhausted = true;
|
||||
return;
|
||||
@@ -62,53 +66,72 @@ namespace StgSharp.HighPerformance.Memory
|
||||
missIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// now prefetch the misses
|
||||
for (int i = 0; i < missIndex; i++)
|
||||
_predictors.RequestSpanOperation();
|
||||
Span<IL4Predict> predictorSpan = _predictors.AsSpan();
|
||||
try
|
||||
{
|
||||
ref CacheLinePrediction handle = ref span[i];
|
||||
nuint address = handle.Address;
|
||||
if (TestHit(address))
|
||||
// now prefetch the misses
|
||||
for (int i = 0; i < missIndex; i++)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
CacheLineHead* head;
|
||||
ref CacheLinePrediction pHandle = ref span[i];
|
||||
nuint address = pHandle.Address;
|
||||
int index;
|
||||
if (_map.TryGet(address, out nuint handle))
|
||||
{
|
||||
head = (CacheLineHead*)handle;
|
||||
index = head->_id;
|
||||
(*_eviction)[index] = 0; // reset eviction counter
|
||||
|
||||
int retryCount = 0, index, remain = missIndex - i;
|
||||
const int maxRetry = 1024;
|
||||
while (!TryGetEmptyLine(out index))
|
||||
{
|
||||
remain = Evict(remain);
|
||||
retryCount++;
|
||||
if (retryCount > maxRetry) {
|
||||
throw new OverflowException($"Failed to evict cache line after {maxRetry} retries.");
|
||||
#region update predictor belonging
|
||||
|
||||
int predictId = head->_predictor;
|
||||
IL4Predict belong = predictorSpan[predictId];
|
||||
if (predict.IsSamePolicy(head->_profile, belong))
|
||||
{
|
||||
head->_predictor = predictId; // wrong line
|
||||
} else
|
||||
{
|
||||
belong.WriteBack(head->_origin, head->_profile, new ReadOnlySpan<byte>((byte*)head->_address, Unsafe.SizeOf<CacheLineData>()));
|
||||
head->_profile = pHandle.MapPolicy;
|
||||
predict.Prefetch(head->_origin, head->_profile, new Span<byte>((byte*)head->_address, Unsafe.SizeOf<CacheLineData>()));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
int retryCount = 0, remain = missIndex - i;
|
||||
const int maxRetry = 1024;
|
||||
while (!TryGetEmptyLine(out index))
|
||||
{
|
||||
remain = Evict(remain);
|
||||
retryCount++;
|
||||
if (retryCount > maxRetry) {
|
||||
throw new OverflowException($"Failed to evict cache line after {maxRetry} retries.");
|
||||
}
|
||||
if (retryCount > maxRetry / 2) {
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
head = &_head[index];
|
||||
head->_id = index;
|
||||
head->_origin = address;
|
||||
head->_profile = pHandle.MapPolicy;
|
||||
head->_refCount = 0;
|
||||
head->_address = (nuint)(_data + index);
|
||||
|
||||
// pre fetch them here
|
||||
predict.Prefetch(head->_origin, head->_profile, new Span<byte>((byte*)head->_address, Unsafe.SizeOf<CacheLineData>()));
|
||||
_ = _map.TryAddOrSet(address, (nuint)head, out _);
|
||||
}
|
||||
CacheLineHead* head = &_head[index];
|
||||
head->_id = index;
|
||||
head->_origin = address;
|
||||
head->_profile = handle.MapPolicy;
|
||||
head->_refCount = 0;
|
||||
head->_address = (nuint)(_data + index);
|
||||
|
||||
// pre fetch them here
|
||||
PrefetchPredict.Prefetch(head->_origin, head->_profile, new Span<byte>((byte*)head->_address, Unsafe.SizeOf<CacheLineData>()));
|
||||
_ = _map.TryAddOrSet(address, (nuint)head, out _);
|
||||
_ = Interlocked.Add(ref _aheadCount, actualCount);
|
||||
}
|
||||
_ = Interlocked.Add(ref _aheadCount, actualCount);
|
||||
}
|
||||
|
||||
private partial bool TestHit(
|
||||
nuint origin
|
||||
)
|
||||
{
|
||||
if (_map.TryGet(origin, out nuint handle))
|
||||
finally
|
||||
{
|
||||
CacheLineHead* head = (CacheLineHead*)handle;
|
||||
int index = head->_id;
|
||||
(*_eviction)[index] = 0; // reset eviction counter
|
||||
return true;
|
||||
_predictors.ReleaseSpanOperation();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user