public override int Analyze() { Console.WriteLine("Starting analysis"); HashSet <NodeId> sourceNodes = new HashSet <NodeId>(); foreach (NodeId nodeId in CachedGraph.DirectedGraph.GetSourceNodes()) { if (PipTable.GetPipType(nodeId.ToPipId()) == PipType.HashSourceFile) { foreach (var edge in CachedGraph.DirectedGraph.GetOutgoingEdges(nodeId)) { sourceNodes.Add(edge.OtherNode); } } else { sourceNodes.Add(nodeId); } } NodeAndCriticalPath[] criticalPaths = new NodeAndCriticalPath[sourceNodes.Count]; Console.WriteLine("Computing critical paths"); VisitationTracker visitedNodes = new VisitationTracker(CachedGraph.DirectedGraph); int i = 0; foreach (var sourceNode in sourceNodes) { criticalPaths[i] = ComputeCriticalPath(sourceNode, visitedNodes); i++; } Console.WriteLine("Sorting critical paths"); Array.Sort(criticalPaths, (c1, c2) => - c1.Time.CompareTo(c2.Time)); Console.WriteLine("Writing critical paths"); int count = Math.Min(m_criticalPathCount, criticalPaths.Length); m_writer.WriteLine("Top {0} critical paths (dependencies first)", count); for (int j = 0; j < count; j++) { var nodeAndCriticalPath = criticalPaths[j]; m_writer.WriteLine("CRITICAL PATH {0}", j + 1); m_writer.WriteLine("TIME: {0} seconds", ToSeconds(nodeAndCriticalPath.Time)); m_writer.WriteLine(); m_writer.WriteLine(PrintCriticalPath(nodeAndCriticalPath, GetElapsed, GetKernelTime, GetUserTime, GetCriticalPath, out var criticalpath)); m_writer.WriteLine(); criticalPathData.criticalPaths.Add(criticalpath); } criticalPathData.wallClockTopPips = PrintQueue("Wall Clock", m_topWallClockPriorityQueue); criticalPathData.userTimeTopPips = PrintQueue("User Time", m_topUserTimePriorityQueue); criticalPathData.kernelTimeTopPips = PrintQueue("Kernel Time", m_topKernelTimePriorityQueue); return(0); }
private void SetCriticalPath(NodeId node, NodeAndCriticalPath criticalPath) { m_criticalPaths[node.Value] = criticalPath; var times = m_elapsedTimes[node.Value]; m_topWallClockPriorityQueue.Add(node, times.WallClockTime); m_topKernelTimePriorityQueue.Add(node, times.KernelTime); m_topUserTimePriorityQueue.Add(node, times.UserTime); }
private NodeAndCriticalPath ComputeCriticalPath(NodeId node, VisitationTracker visitedNodes) { var criticalPath = GetCriticalPath(node); if (criticalPath.Node.IsValid) { return(criticalPath); } criticalPath = new NodeAndCriticalPath() { Node = node, Time = GetElapsed(node), }; if (!visitedNodes.MarkVisited(node)) { return(criticalPath); } NodeAndCriticalPath maxDependencyCriticalPath = default(NodeAndCriticalPath); foreach (var dependency in CachedGraph.DirectedGraph.GetOutgoingEdges(node)) { var dependencyCriticalPath = ComputeCriticalPath(dependency.OtherNode, visitedNodes); if (dependencyCriticalPath.Time > maxDependencyCriticalPath.Time) { maxDependencyCriticalPath = dependencyCriticalPath; } } criticalPath.Next = maxDependencyCriticalPath.Node; criticalPath.Time += maxDependencyCriticalPath.Time; SetCriticalPath(node, criticalPath); return(criticalPath); }
internal string PrintCriticalPath( NodeAndCriticalPath nodeAndCriticalPath, GetElapsedLookup getElapsed, GetKernelTimeLookup getKernelTime, GetUserTimeLookup getUserTime, GetCriticalPathLookup getCriticalPath, out Model.CriticalPath criticalPath) { Contract.Assert(getElapsed != null, "getElapsed must be set."); Contract.Assert(getCriticalPath != null, "getCriticalPath must be set."); Contract.Assert(!nodeAndCriticalPath.Equals(default(NodeAndCriticalPath)), "nodeAndCriticalPath must be set."); criticalPath = new Model.CriticalPath(); ConcurrentDictionary <PathAtom, TimeSpan> toolStats = new ConcurrentDictionary <PathAtom, TimeSpan>(); var totalTimeWidth = ToSeconds(nodeAndCriticalPath.Time).Length; var totalKernelTimeWidth = ToSeconds(nodeAndCriticalPath.KernelTime).Length; var totalUserTimeWidth = ToSeconds(nodeAndCriticalPath.UserTime).Length; criticalPath.time = ToSeconds(nodeAndCriticalPath.Time); TimeSpan startTime = new TimeSpan(0); using (var output = new StringWriter(CultureInfo.InvariantCulture)) { using (var criticalPathWriter = new StringWriter(CultureInfo.InvariantCulture)) { while (true) { var pip = CachedGraph.PipGraph.GetPipFromUInt32(nodeAndCriticalPath.Node.Value); var process = pip as Process; var elapsed = getElapsed(nodeAndCriticalPath.Node); var kernelTime = getKernelTime(nodeAndCriticalPath.Node); var userTime = getUserTime(nodeAndCriticalPath.Node); if (process != null) { toolStats.AddOrUpdate(process.GetToolName(CachedGraph.Context.PathTable), elapsed, (k, v) => v + elapsed); } var node = new Node(); node.pipId = pip.PipId.Value.ToString("X16", CultureInfo.InvariantCulture).TrimStart(new Char[] { '0' }); node.semiStableHash = pip.SemiStableHash.ToString("X"); node.pipType = pip.PipType.ToString(); node.duration = ToSeconds(elapsed); node.kernelTime = ToSeconds(kernelTime); node.userTime = ToSeconds(userTime); node.shortDescription = pip.GetShortDescription(CachedGraph.Context); node.startTime = ToSeconds(startTime); startTime = startTime + elapsed; criticalPath.nodes.Add(node); criticalPathWriter.Write( "({0}) ({2}) ({3}) [{1}]", ToSeconds(elapsed).PadLeft(totalTimeWidth), pip.GetDescription(CachedGraph.Context), ToSeconds(kernelTime).PadLeft(totalKernelTimeWidth), ToSeconds(userTime).PadLeft(totalUserTimeWidth)); if (nodeAndCriticalPath.Next.IsValid) { criticalPathWriter.WriteLine(" =>"); } else { criticalPathWriter.WriteLine(); break; } nodeAndCriticalPath = getCriticalPath(nodeAndCriticalPath.Next); } output.WriteLine("TOOL STATS:"); foreach (var toolStatEntry in toolStats.OrderByDescending(kvp => kvp.Value)) { output.WriteLine( "{0}, {1}", ToSeconds(toolStatEntry.Value).PadLeft(totalTimeWidth), toolStatEntry.Key.ToString(CachedGraph.Context.StringTable)); var toolStat = new ToolStat(); toolStat.name = toolStatEntry.Key.ToString(CachedGraph.Context.StringTable); toolStat.time = ToSeconds(toolStatEntry.Value); criticalPath.toolStats.Add(toolStat); } output.WriteLine(); output.WriteLine("( Duration ) ( Kernel Time ) ( User Time ) Seconds :: CRITICAL PATH DEPENDENCY LIST:"); output.Write(criticalPathWriter.ToString()); } return(output.ToString()); } }