Skip to content

Commit

Permalink
Change source view to include both the inclusive samples data as well…
Browse files Browse the repository at this point in the history
… as the exclusive samples data (#1864)
  • Loading branch information
davidwrighton authored May 25, 2023
1 parent a79143b commit 873a2d0
Showing 1 changed file with 45 additions and 24 deletions.
69 changes: 45 additions & 24 deletions src/PerfView/StackViewer/StackWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2297,7 +2297,8 @@ private void DoGotoSource(object sender, ExecutedRoutedEventArgs e)
}

SortedDictionary<int, float> metricOnLine;
var sourceLocation = GetSourceLocation(asCallTreeNodeBase, cellText, out metricOnLine);
SortedDictionary<int, float> exclusiveMetricOnLine;
var sourceLocation = GetSourceLocation(asCallTreeNodeBase, cellText, out metricOnLine, out exclusiveMetricOnLine);

string sourcePathToOpen = null;
string logicalSourcePath = null;
Expand All @@ -2321,7 +2322,7 @@ private void DoGotoSource(object sender, ExecutedRoutedEventArgs e)
{
sourcePathToOpen = CacheFiles.FindFile(sourcePathToOpen, Path.GetExtension(sourcePathToOpen));
StatusBar.Log("Annotating source with metric to the file " + sourcePathToOpen);
AnnotateLines(logicalSourcePath, sourcePathToOpen, metricOnLine);
AnnotateLines(logicalSourcePath, sourcePathToOpen, ("Inc", metricOnLine) ,("Exc", exclusiveMetricOnLine));
}
}
}
Expand Down Expand Up @@ -2360,9 +2361,10 @@ private void DoGotoSource(object sender, ExecutedRoutedEventArgs e)

// TODO FIX NOW review
private SourceLocation GetSourceLocation(CallTreeNodeBase asCallTreeNodeBase, string cellText,
out SortedDictionary<int, float> metricOnLine)
out SortedDictionary<int, float> metricOnLine, out SortedDictionary<int, float> exclusiveMetricOnLine)
{
metricOnLine = null;
exclusiveMetricOnLine = null;
var m = Regex.Match(cellText, "<<(.*!.*)>>");
if (m.Success)
{
Expand All @@ -2372,12 +2374,14 @@ private SourceLocation GetSourceLocation(CallTreeNodeBase asCallTreeNodeBase, st
// Find the most numerous call stack
// TODO this can be reasonably expensive. If it is a problem do something about it (e.g. sampling)
var frameIndexCounts = new Dictionary<StackSourceFrameIndex, float>();
var exclusiveFrameIndexCounts = new Dictionary<StackSourceFrameIndex, float>();
asCallTreeNodeBase.GetSamples(false, delegate (StackSourceSampleIndex sampleIdx)
{
// Find the callStackIdx which corresponds to the name in the cell, and log it to callStackIndexCounts
var matchingFrameIndex = StackSourceFrameIndex.Invalid;
var sample = m_stackSource.GetSampleByIndex(sampleIdx);
var callStackIdx = sample.StackIndex;
bool exclusiveSample = true;
while (callStackIdx != StackSourceCallStackIndex.Invalid)
{
var frameIndex = m_stackSource.GetFrameIndex(callStackIdx);
Expand All @@ -2387,6 +2391,13 @@ private SourceLocation GetSourceLocation(CallTreeNodeBase asCallTreeNodeBase, st
matchingFrameIndex = frameIndex; // We keep overwriting it, so we get the entry closest to the root.
}

if (exclusiveSample)
{
exclusiveSample = false;
float count = 0;
exclusiveFrameIndexCounts.TryGetValue(matchingFrameIndex, out count);
exclusiveFrameIndexCounts[matchingFrameIndex] = count + sample.Metric;
}
callStackIdx = m_stackSource.GetCallerIndex(callStackIdx);
}
if (matchingFrameIndex != StackSourceFrameIndex.Invalid)
Expand Down Expand Up @@ -2437,18 +2448,25 @@ private SourceLocation GetSourceLocation(CallTreeNodeBase asCallTreeNodeBase, st
if (sourceLocation != null)
{
var filePathForMax = sourceLocation.SourceFile.BuildTimeFilePath;
metricOnLine = new SortedDictionary<int, float>();
// Accumulate the counts on a line basis
foreach (StackSourceFrameIndex frameIdx in frameIndexCounts.Keys)
AccumulateCounts(frameIndexCounts, out metricOnLine);
AccumulateCounts(exclusiveFrameIndexCounts, out exclusiveMetricOnLine);

void AccumulateCounts(Dictionary<StackSourceFrameIndex, float> indexCounts, out SortedDictionary<int, float> metricHash)
{
var loc = asTraceEventStackSource.GetSourceLine(frameIdx, reader);
if (loc != null && loc.SourceFile.BuildTimeFilePath == filePathForMax)
metricHash = new SortedDictionary<int, float>();

foreach (StackSourceFrameIndex frameIdx in indexCounts.Keys)
{
frameToLine[frameIdx] = loc.LineNumber;
float metric;
metricOnLine.TryGetValue(loc.LineNumber, out metric);
metric += frameIndexCounts[frameIdx];
metricOnLine[loc.LineNumber] = metric;
var loc = asTraceEventStackSource.GetSourceLine(frameIdx, reader);
if (loc != null && loc.SourceFile.BuildTimeFilePath == filePathForMax)
{
frameToLine[frameIdx] = loc.LineNumber;
float metric;
metricHash.TryGetValue(loc.LineNumber, out metric);
metric += indexCounts[frameIdx];
metricHash[loc.LineNumber] = metric;
}
}
}
}
Expand Down Expand Up @@ -2509,7 +2527,7 @@ private SourceLocation GetSourceLocation(CallTreeNodeBase asCallTreeNodeBase, st
return sourceLocation;
}

private void AnnotateLines(string inFileName, string outFileName, SortedDictionary<int, float> lineData)
private void AnnotateLines(string inFileName, string outFileName, params ValueTuple<string, SortedDictionary<int, float>>[] lineData)
{
using (var inFile = File.OpenText(inFileName))
using (var outFile = File.CreateText(outFileName))
Expand All @@ -2525,18 +2543,21 @@ private void AnnotateLines(string inFileName, string outFileName, SortedDictiona

lineNum++;

float value;
if (lineData.TryGetValue(lineNum, out value))
{
outFile.Write(ToCompactString(value));
}
else if (lineNum == 1)
{
outFile.Write("Metric|");
}
else
foreach (var data in lineData)
{
outFile.Write(" ");
float value;
if (data.Item2.TryGetValue(lineNum, out value))
{
outFile.Write(ToCompactString(value));
}
else if (lineNum == 1)
{
outFile.Write($"{data.Item1.PadLeft(6)}|");
}
else
{
outFile.Write(" ");
}
}

outFile.WriteLine(line);
Expand Down

0 comments on commit 873a2d0

Please sign in to comment.