Ejemplo n.º 1
0
        public void EverythingAsync()
        {
            const int MaxExecTime = 24 * 3600 * 1000;

            var stream = new MemoryStream();
            var r      = new Random(0);

            for (int i = 0; i < 10; i++)
            {
                int seed = r.Next(100 * 1000);
                PipRuntimeTimeTable table = new PipRuntimeTimeTable();
                XAssert.IsTrue(table.Count == 0);

                var s      = new Random(seed);
                var buffer = new byte[sizeof(long)];
                for (int j = 0; j < 10; j++)
                {
                    s.NextBytes(buffer);
                    long semiStableHash = BitConverter.ToInt64(buffer, 0);

                    int execTime = s.Next(MaxExecTime);
                    var processPipExecutionPerformance = new ProcessPipExecutionPerformance(
                        PipExecutionLevel.Executed,
                        DateTime.UtcNow,
                        DateTime.UtcNow.AddMilliseconds(execTime),
                        FingerprintUtilities.ZeroFingerprint,
                        TimeSpan.FromMilliseconds(execTime),
                        default(FileMonitoringViolationCounters),
                        default(IOCounters),
                        TimeSpan.FromMilliseconds(execTime),
                        TimeSpan.FromMilliseconds(execTime / 2),
                        1024 * 1024,
                        1,
                        workerId: 0);

                    PipHistoricPerfData runTimeData = new PipHistoricPerfData(processPipExecutionPerformance);
                    table[semiStableHash] = runTimeData;
                }

                XAssert.IsTrue(table.Count == 10);

                stream.Position = 0;
                table.Save(stream);
                stream.Position = 0;
                table           = PipRuntimeTimeTable.Load(stream);
                XAssert.IsTrue(table.Count == 10);

                s = new Random(seed);
                for (int j = 0; j < 10; j++)
                {
                    s.NextBytes(buffer);
                    long semiStableHash = BitConverter.ToInt64(buffer, 0);
                    XAssert.IsTrue(table[semiStableHash].DurationInMs >= (uint)s.Next(MaxExecTime));
                }
            }
        }
Ejemplo n.º 2
0
        public TestScheduler(
            PipGraph graph,
            TestPipQueue pipQueue,
            PipExecutionContext context,
            FileContentTable fileContentTable,
            EngineCache cache,
            IConfiguration configuration,
            FileAccessWhitelist fileAccessWhitelist,
            DirectoryMembershipFingerprinterRuleSet directoryMembershipFingerprinterRules = null,
            ITempCleaner tempCleaner                  = null,
            PipRuntimeTimeTable runningTimeTable      = null,
            JournalState journalState                 = null,
            PerformanceCollector performanceCollector = null,
            string fingerprintSalt = null,
            PreserveOutputsInfo?previousInputsSalt = null,
            IEnumerable <Pip> successfulPips       = null,
            IEnumerable <Pip> failedPips           = null,
            LoggingContext loggingContext          = null,
            IIpcProvider ipcProvider = null,
            DirectoryTranslator directoryTranslator = null,
            VmInitializer vmInitializer             = null,
            SchedulerTestHooks testHooks            = null) : base(graph, pipQueue, context, fileContentTable, cache,
                                                                   configuration, fileAccessWhitelist, loggingContext, null, directoryMembershipFingerprinterRules,
                                                                   tempCleaner, AsyncLazy <PipRuntimeTimeTable> .FromResult(runningTimeTable), performanceCollector, fingerprintSalt, previousInputsSalt,
                                                                   ipcProvider: ipcProvider,
                                                                   directoryTranslator: directoryTranslator,
                                                                   journalState: journalState,
                                                                   vmInitializer: vmInitializer,
                                                                   testHooks: testHooks)
        {
            m_testPipQueue = pipQueue;

            if (successfulPips != null)
            {
                foreach (var pip in successfulPips)
                {
                    Contract.Assume(pip.PipId.IsValid, "Override results must be added after the pip has been added to the scheduler");
                    m_overridePipResults.Add(pip.PipId, PipResultStatus.Succeeded);
                }
            }

            if (failedPips != null)
            {
                foreach (var pip in failedPips)
                {
                    Contract.Assume(pip.PipId.IsValid, "Override results must be added after the pip has been added to the scheduler");
                    m_overridePipResults.Add(pip.PipId, PipResultStatus.Failed);
                }
            }

            m_loggingContext = loggingContext;
        }
Ejemplo n.º 3
0
        public void TimeToLive()
        {
            int execTime = 1;
            var processPipExecutionPerformance = new ProcessPipExecutionPerformance(
                PipExecutionLevel.Executed,
                DateTime.UtcNow,
                DateTime.UtcNow.AddMilliseconds(execTime),
                FingerprintUtilities.ZeroFingerprint,
                TimeSpan.FromMilliseconds(execTime),
                default(FileMonitoringViolationCounters),
                default(IOCounters),
                TimeSpan.FromMilliseconds(execTime),
                TimeSpan.FromMilliseconds(execTime / 2),
                1024 * 1024,
                1,
                workerId: 0);

            PipHistoricPerfData runTimeData = new PipHistoricPerfData(processPipExecutionPerformance);
            PipRuntimeTimeTable table       = new PipRuntimeTimeTable();
            var semiStableHashToKeep        = 0;

            table[semiStableHashToKeep] = runTimeData;
            var semiStableHashToDrop = 1;

            table[semiStableHashToDrop] = runTimeData;
            var stream = new MemoryStream();

            for (int i = 0; i < PipHistoricPerfData.DefaultTimeToLive; i++)
            {
                stream.Position = 0;
                table.Save(stream);
                stream.Position = 0;
                table           = PipRuntimeTimeTable.Load(stream);
                Analysis.IgnoreResult(table[semiStableHashToKeep]);
            }

            stream.Position = 0;
            table           = PipRuntimeTimeTable.Load(stream);
            XAssert.AreEqual(1u, table[semiStableHashToKeep].DurationInMs);
            XAssert.AreEqual(0u, table[semiStableHashToDrop].DurationInMs);
        }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
            PipExecutionData data = new PipExecutionData();

            if (args.Length != 1)
            {
                throw new ArgumentException("Specify directory path as only argument on command line");
            }

            string directory = args[0];
            string graphPath = Path.Combine(args[0], "graph.json");

            if (!File.Exists(graphPath))
            {
                throw new ArgumentException(string.Format("Graph does not exist at location: {0}", graphPath));
            }


            string resultsFormat = string.Format(@"{0}\sim\{{0}}", directory);

            Console.WriteLine("Loading graph...");

            Directory.CreateDirectory(string.Format(resultsFormat, ""));
            data.ReadAndCacheJsonGraph(Path.Combine(directory, "graph.json"));

            Console.WriteLine("Done");
            Console.WriteLine();

            Console.WriteLine("Saving runtime time table:");

            PipRuntimeTimeTable runtimeTable = new PipRuntimeTimeTable();

            foreach (var node in data.DataflowGraph.Nodes)
            {
                if (data.PipTypes[node] == PipType.Process)
                {
                    var  stableId     = (long)data.SemiStableHashes[node];
                    var  duration     = TimeSpan.FromTicks((long)data.Durations[node]);
                    uint milliseconds = (uint)Math.Min(duration.TotalMilliseconds, uint.MaxValue);
                    runtimeTable[stableId] = new PipHistoricPerfData(PipHistoricPerfData.DefaultTimeToLive, milliseconds);
                }
            }

            runtimeTable.SaveAsync(Path.Combine(directory, "RunningTimeTable")).Wait();

            Console.WriteLine("Done");
            Console.WriteLine();


            using (StreamWriter sw = new StreamWriter(resultsFormat.FormatWith("result.txt")))
            {
                var writers = new MultiWriter(sw, Console.Out);
                writers.WriteLine("Edge Count: {0}", data.DataflowGraph.EdgeCount);
                writers.WriteLine("Pip Type Counts:");
                foreach (var pipType in EnumTraits <PipType> .EnumerateValues())
                {
                    writers.WriteLine("{0}: {1}", data.PipTypeCounts[(int)pipType].ToString().PadLeft(10), pipType);
                }

                writers.WriteLine("Processes with timing information:{0} ", data.DataflowGraph.Nodes.Where(node => data.PipTypes[node] == PipType.Process && data.StartTimes[node] != 0).Count());

                File.WriteAllLines(resultsFormat.FormatWith("actual.durations.csv"), data.Spans.Where(ps => data.PipTypes[ps.Id] == PipType.Process).Select(ps => string.Join(",", data.GetName(ps.Id), ps.Duration.ToMinutes().ToString())));
                File.WriteAllLines(resultsFormat.FormatWith("actual.durations.txt"), data.Spans.Select(ps => ps.Duration.ToMinutes().ToString()));
                File.WriteAllLines(resultsFormat.FormatWith("actual.starts.txt"), data.Spans.Select(ps => ps.StartTime.ToMinutes().ToString()));
                File.WriteAllLines(resultsFormat.FormatWith("actual.ends.txt"), data.Spans.Select(ps => ps.EndTime.ToMinutes().ToString()));

                CreateSpanImage(resultsFormat.FormatWith("actual.png"), data.Spans, data.TotalDuration, Math.Max(data.ActualConcurrency, 1));

                SimulationResult actualSimulation = null;
                if (true)
                {
                    Console.WriteLine("Simulating actual build");
                    actualSimulation = new SimulationResult(data, data.AggregateCosts);
                    actualSimulation.Simulate((uint)data.ActualConcurrency);

                    File.WriteAllLines(resultsFormat.FormatWith("actualSimulation.durations.txt"), actualSimulation.GetSpans().Select(ps => ps.Duration.ToMinutes().ToString()));
                    File.WriteAllLines(resultsFormat.FormatWith("actualSimulation.starts.txt"), actualSimulation.GetSpans().Select(ps => ps.StartTime.ToMinutes().ToString()));
                    File.WriteAllLines(resultsFormat.FormatWith("actualSimulation.ends.txt"), actualSimulation.GetSpans().Select(ps => ps.EndTime.ToMinutes().ToString()));

                    string csvFormat = "{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}";


                    File.WriteAllLines(resultsFormat.FormatWith("actualSimulation.txt"), new string[] { csvFormat.FormatWith("Id", "Thread", "Minimum Start Time", "Start Time", "End Time", "Duration", "Incoming", "Outgoing") }.Concat(actualSimulation.GetSpans().Select(ps =>
                                                                                                                                                                                                                                                                             csvFormat.FormatWith(
                                                                                                                                                                                                                                                                                 ps.Id.Value,
                                                                                                                                                                                                                                                                                 ps.Thread,
                                                                                                                                                                                                                                                                                 actualSimulation.MinimumStartTimes[ps.Id].ToMinutes(),
                                                                                                                                                                                                                                                                                 ps.StartTime.ToMinutes(),
                                                                                                                                                                                                                                                                                 ps.EndTime.ToMinutes(),
                                                                                                                                                                                                                                                                                 ps.Duration.ToMinutes(),
                                                                                                                                                                                                                                                                                 data.DataflowGraph.GetIncomingEdgesCount(ps.Id),
                                                                                                                                                                                                                                                                                 data.DataflowGraph.GetIncomingEdgesCount(ps.Id)))));

                    CreateSimulationImage(actualSimulation, resultsFormat.FormatWith("actualSimulation.png"));

                    Console.WriteLine("Done");
                }

                Console.WriteLine();


                writers.WriteLine("Actual Total Build Time: {0} min", data.TotalDuration.ToMinutes());
                writers.WriteLine("Actual Concurrency: {0}", data.ActualConcurrency);
                if (actualSimulation != null)
                {
                    writers.WriteLine("Simulated total build time (using actual concurrency): {0} min", actualSimulation.TotalTime.ToMinutes());
                }

                int nameWidth;

                int   count            = 0;
                ulong criticalPathCost = 0;
                foreach (var p in data.GetSortedPips(20, true, n => data.PipTypes[n] == PipType.Process, n => data.AggregateCosts[n]))
                {
                    List <NodeId> criticalPath      = new List <NodeId>();
                    NodeId        criticalChainNode = p.Node;
                    while (criticalChainNode.IsValid())
                    {
                        criticalPath.Add(criticalChainNode);
                        criticalChainNode = data.CriticalChain[criticalChainNode];
                    }

                    p.Priority.Max(ref criticalPathCost);

                    writers.WriteLine("Critical Path {0}:", count++);
                    writers.WriteLine("Critical Path Cost: {0} min", p.Priority.ToMinutes());
                    writers.WriteLine("Critical Path Length: {0}", criticalPath.Count);
                    nameWidth = criticalPath.Select(n => data.GetName(n).Length).Max();
                    writers.WriteLine("Critical Path:\n    {0}", string.Join(Environment.NewLine + " -> ", criticalPath
                                                                             //.Where(n => data.Durations[n] > 0)
                                                                             .Select(n => string.Format("{0} ({1} min) [{2}] <{3}>", data.GetName(n).PadLeft(nameWidth), data.Durations[n].ToMinutes(), data.PipIds[n], data.PipTypes[n]))));
                }


                nameWidth = data.LongestRunningPips.Select(n => data.GetName(n.Node).Length).Max();
                writers.WriteLine();
                writers.WriteLine("Top 20 Long Running Pips:");
                foreach (var p in data.LongestRunningPips)
                {
                    writers.WriteLine("{0} [{2}]: {1} min", data.GetName(p.Node).PadLeft(nameWidth), p.Priority.ToMinutes(), data.PipIds[p.Node]);
                }

                writers.WriteLine();
                writers.WriteLine("Bottom 20 Shortest Running Processes:");
                foreach (var p in data.ShortestRunningProcesses)
                {
                    writers.WriteLine("{0} [{2}]: {1} min", data.GetName(p.Node).PadLeft(nameWidth), p.Priority.ToMinutes(), data.PipIds[p.Node]);
                }

                int    simulationCount = 1;
                int    increment       = 70;
                int?[] threadCounts    = new int?[simulationCount];
                threadCounts[0] = 60;
                //threadCounts[0] = 60;
                //threadCounts[4] = 330;
                //threadCounts[5] = 400;
                //threadCounts[6] = 470;
                SimulationResult[] results = new SimulationResult[simulationCount];
                Parallel.For(0, simulationCount, i =>
                {
                    var threadCount = threadCounts[i] ?? ((i + 1) * increment);
                    Console.WriteLine("Simulating {0}...", threadCount);
                    SimulationResult result = new SimulationResult(data, data.AggregateCosts);
                    result.Simulate((uint)threadCount);
                    results[i] = result;
                    Console.WriteLine("Done {0}", threadCount);

                    //Console.WriteLine("Simulating adjusted{0}...", threadCount);
                    //SimulationResult adjusted = new SimulationResult(data, data.ComputeAggregateCosts(result.GetAdjustedDurations(criticalPathCost)));
                    //result.Simulate((uint)threadCount);
                    //results[i + simulationCount] = result;
                    //Console.WriteLine("Done adjusted {0}", threadCount);

                    //i = i + (results.Length / 2);

                    //Console.WriteLine("Simulating {0}...", i);
                    //SimulationResult adjusted = new SimulationResult(data, result.EndTimes);
                    //adjusted.Simulate((uint)result.Threads.Count);
                    //results[i] = adjusted;
                    //Console.WriteLine("Done {0}", i);
                });

                results = results.OrderBy(s => s.Threads.Count).ToArray();

                string format = "{0}, {1}, {5}, {6}";
                writers.WriteLine();
                writers.WriteLine("Results");
                writers.WriteLine(format,
                                  "Thread Count",                  // 0
                                  "Total Execution Time (min)",    // 1
                                  "Critical Path Length",          // 2
                                  "Critical Path Tail Pip",        // 3
                                  "Critical Path Idle Time (min)", // 4
                                  "Average Utilization",           // 5
                                  "Max Path Length",               // 6
                                  "Executed Pips"                  // 7
                                  );

                for (int i = 0; i < results.Length; i++)
                {
                    var result = results[i];
                    writers.WriteLine(format,
                                      result.Threads.Count,
                                      result.TotalTime.ToMinutes(),
                                      result.CriticalPath.Executions.Count,
                                      result.CriticalPath.Executions.Last().Id.Value,
                                      result.CriticalPath.IdleTime.ToMinutes(),
                                      Math.Round((double)result.TotalActiveTime / (double)((ulong)result.Threads.Count * result.TotalTime), 3),
                                      result.Threads.Select(t => t.Executions.Count).Max(),
                                      result.Threads.Select(t => t.Executions.Count).Sum());

                    CreateSimulationImage(result, resultsFormat.FormatWith("simulation.{0}.png".FormatWith(result.Threads.Count)));
                }
            }
        }