[Profile] Classify what changed in stale resource cache entries
This commit is contained in:
parent
7b730a51fc
commit
22ec74e085
|
|
@ -828,7 +828,61 @@ public sealed class ResourceMaterializationCache
|
|||
var refusals = string.Join(",", RefreshRefusalNames.Select((name, index) => FormattableString.Invariant($"{name}:{Interlocked.Exchange(ref _refreshRefusals[index], 0)}")));
|
||||
var total = hits + misses;
|
||||
return FormattableString.Invariant(
|
||||
$"[PERF][RESOURCE_CACHE] hits={hits} misses={misses} not_found={notFound} stale={stale} stale_unreadable={staleUnreadable} refreshes={refreshes} refused={refusals} uncacheable={uncacheable} hit_rate={(total == 0 ? 0 : hits * 100.0 / total):F1}% {RawReadPrefetch.TakeReport()}");
|
||||
$"[PERF][RESOURCE_CACHE] hits={hits} misses={misses} not_found={notFound} stale={stale} stale_unreadable={staleUnreadable} refreshes={refreshes} refused={refusals} uncacheable={uncacheable} hit_rate={(total == 0 ? 0 : hits * 100.0 / total):F1}% {RawReadPrefetch.TakeReport()}") +
|
||||
TakeStaleDifferenceReport();
|
||||
}
|
||||
|
||||
private static readonly bool StaleDiffEnabled = Environment.GetEnvironmentVariable("SHARPEMU_PROFILE_PERFORMANCE") == "1";
|
||||
private static readonly System.Collections.Concurrent.ConcurrentDictionary<string, long> _staleDifferences = new(StringComparer.Ordinal);
|
||||
|
||||
private static void NoteStaleDifference(Entry stale, Entry built)
|
||||
{
|
||||
var parts = new SortedSet<string>(StringComparer.Ordinal);
|
||||
if (!stale.Specialization.Equals(built.Specialization))
|
||||
parts.Add("spec");
|
||||
DifferingWords("buf", stale.Snapshot.Buffers, built.Snapshot.Buffers, parts);
|
||||
DifferingWords("img", stale.Snapshot.Images, built.Snapshot.Images, parts);
|
||||
DifferingWords("smp", stale.Snapshot.Samplers, built.Snapshot.Samplers, parts);
|
||||
if (!stale.Snapshot.FlattenedResourceTable.AsSpan().SequenceEqual(built.Snapshot.FlattenedResourceTable))
|
||||
parts.Add("table");
|
||||
if (!stale.Snapshot.DeviceAddressRanges.AsSpan().SequenceEqual(built.Snapshot.DeviceAddressRanges))
|
||||
parts.Add("ranges");
|
||||
if (stale.Bytes.Length != built.Bytes.Length || !stale.RangeAddresses.AsSpan().SequenceEqual(built.RangeAddresses))
|
||||
parts.Add("reads_moved");
|
||||
var signature = parts.Count == 0 ? "none" : string.Join("+", parts);
|
||||
_staleDifferences.AddOrUpdate(signature, 1, static (_, count) => count + 1);
|
||||
}
|
||||
|
||||
private static void DifferingWords(string name, uint[][] left, uint[][] right, SortedSet<string> parts)
|
||||
{
|
||||
if (left.Length != right.Length)
|
||||
{
|
||||
parts.Add($"{name}.count");
|
||||
return;
|
||||
}
|
||||
|
||||
for (var index = 0; index < left.Length; index++)
|
||||
{
|
||||
if (left[index].Length != right[index].Length)
|
||||
{
|
||||
parts.Add($"{name}.length");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var word = 0; word < left[index].Length; word++)
|
||||
if (left[index][word] != right[index][word])
|
||||
parts.Add($"{name}.w{word}");
|
||||
}
|
||||
}
|
||||
|
||||
private static string TakeStaleDifferenceReport()
|
||||
{
|
||||
if (_staleDifferences.IsEmpty)
|
||||
return string.Empty;
|
||||
var ranked = _staleDifferences.ToArray().OrderByDescending(pair => pair.Value).Take(10).ToArray();
|
||||
_staleDifferences.Clear();
|
||||
return Environment.NewLine + string.Join(Environment.NewLine,
|
||||
ranked.Select(pair => FormattableString.Invariant($"[PERF][RESOURCE_STALE_DIFF] n={pair.Value} changed={pair.Key}")));
|
||||
}
|
||||
|
||||
// The first part a cached result differs from a fresh one in, or null when they are the same.
|
||||
|
|
@ -1007,6 +1061,8 @@ public sealed class ResourceMaterializationCache
|
|||
}
|
||||
|
||||
var built = recorder.Build(plan, inputs, snapshot, specialization, rebase.MemoryBases);
|
||||
if (StaleDiffEnabled && stale is not null && learning is null)
|
||||
NoteStaleDifference(stale, built);
|
||||
if (learning is { } pending)
|
||||
{
|
||||
var agrees = Difference(pending.Snapshot, pending.From.Specialization, built.Snapshot, built.Specialization) is null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue