/base/Applications/Benchmarks/CreateProcess/CreateProcess.cs
C# | 431 lines | 339 code | 54 blank | 38 comment | 15 complexity | d831d0fbc43dd6fc2960b218c1219342 MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Microsoft Research Singularity
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // Note: Singularity micro-benchmark program.
- //
- using Microsoft.Singularity;
- using Microsoft.Singularity.V1.Services;
- using Microsoft.Singularity.V1.Threads;
- using System;
- using System.Runtime.CompilerServices;
- using System.Diagnostics;
- using System.Threading;
-
- using Microsoft.Singularity.Channels;
- using Microsoft.Contracts;
- using Microsoft.SingSharp.Reflection;
- using Microsoft.Singularity.Applications;
- using Microsoft.Singularity.Io;
- using Microsoft.Singularity.Configuration;
- [assembly: Transform(typeof(ApplicationResourceTransform))]
-
- namespace Microsoft.Singularity.Applications
- {
- [ConsoleCategory(HelpMessage="CreateProcess benchmark test", DefaultAction=true)]
- internal class Parameters
- {
- [InputEndpoint("data")]
- public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
-
- [BoolParameter( "q", Default=false, HelpMessage="Quiet Mode.")]
- internal bool quietMode;
-
- [LongParameter( "r", Default=1, HelpMessage="Repetition count.")]
- internal long repetitions;
-
- reflective internal Parameters();
-
- internal int AppMain() {
- return CreateProcessTest.AppMain(this);
- }
- }
-
- //
- // The goal of this test is to time how long it takes to
- // create a process.
- //
- public class CreateProcessTest
- {
- private static bool AtRing3;
-
- #if x64_PERF
- [CLSCompliant(false)]
- public struct PerfEvtSel
- {
- // Bits and Flags
- public const uint CNT_MASK = 0xff000000;
- public const uint INV = 0x00800000;
- public const uint EN = 0x00400000;
- public const uint INT = 0x00100000;
- public const uint PC = 0x00080000;
- public const uint E = 0x00040000;
- public const uint OS = 0x00020000;
- public const uint USR = 0x00010000;
- public const uint UNIT_MASK = 0x0000ff00;
- public const uint SELECTOR = 0x000000ff;
-
- // Common setting: Count all, but don't interrupt,
- public const uint COUNT = (EN | PC | OS | USR);
-
- // Selector values.
- public const uint DtlbL1MissL2Hit = 0x45; // Speculative
- public const uint DtlbL1MissL2Miss = 0x46; // Speculative
- public const uint CyclesNotHalted = 0x76;
- public const uint RequestsToL2Cache = 0x7d;
- public const uint ItlbL1MissL2Hit = 0x84;
- public const uint ItlbL1MissL2Miss = 0x85;
- public const uint RetiredInstructions = 0xc0;
- public const uint RetiredBranchInstructions = 0xc2;
- public const uint RetiredBranchesMispredicted = 0xc3;
- public const uint RetiredBranchesTaken = 0xc4;
- public const uint CyclesInterruptsMasked = 0xcd;
- public const uint CyclesInterruptsBlocked = 0xce;
- }
-
- public static void Reset(uint pmc, ulong value)
- {
- // Clear the event selector.
- Processor.WriteMsr(0xc0010000 + pmc, 0);
- // Clear the performance counter.
- Processor.WriteMsr(0xc0010004 + pmc, 0);
- // Enable the event selector.
- Processor.WriteMsr(0xc0010000 + pmc, value);
- }
-
- public static string EvtSelToString(ulong value)
- {
- switch (value & 0xff) {
- case PerfEvtSel.DtlbL1MissL2Hit: return "DTLB_L2_Hit";
- case PerfEvtSel.DtlbL1MissL2Miss: return "DTBL_L2_Miss";
- case PerfEvtSel.CyclesNotHalted: return "CyclesNotHalted";
- case PerfEvtSel.RequestsToL2Cache: return "TLB_L2_Requests";
- case PerfEvtSel.ItlbL1MissL2Hit: return "ITLB_L2_Hit";
- case PerfEvtSel.ItlbL1MissL2Miss: return "ITLB_L2_Miss";
- case PerfEvtSel.RetiredInstructions: return "Retired_Inst.";
- case PerfEvtSel.RetiredBranchInstructions: return "Branches";
- case PerfEvtSel.RetiredBranchesMispredicted:return "Br_Mispredicted";
- case PerfEvtSel.RetiredBranchesTaken: return "Br_Taken";
- case PerfEvtSel.CyclesInterruptsMasked: return "Ints_Masked (cyc)";
- case PerfEvtSel.CyclesInterruptsBlocked: return "Ints_Blocked (cyc)";
- default:
- return String.Format("{0:x16}", value);
- }
- }
-
- private static ulong x64_i0, x64_p0;
- private static ulong x64_i1, x64_p1;
- private static ulong x64_i2, x64_p2;
- private static ulong x64_i3, x64_p3;
- #endif
-
- private static void DualWriteLine(string message)
- {
- Console.WriteLine(message);
- DebugStub.WriteLine(message);
- }
-
- public struct PerfSnap
- {
- private bool disabled;
- private long begCycleCount;
- private long endCycleCount;
- private long begSwitchCount;
- private long endSwitchCount;
- private long begInterruptCount;
- private long endInterruptCount;
- private long begKernelGcCount;
- private long endKernelGcCount;
- private long begProcessGcCount;
- private long endProcessGcCount;
- private long iterations;
- private ulong begAllocatedCount;
- private ulong begAllocatedBytes;
- private ulong begFreedCount;
- private ulong begFreedBytes;
- private ulong endAllocatedCount;
- private ulong endAllocatedBytes;
- private ulong endFreedCount;
- private ulong endFreedBytes;
- private ulong begStackGets;
- private ulong begStackRets;
- private ulong endStackGets;
- private ulong endStackRets;
-
-
- public long Cycles { get { return endCycleCount - begCycleCount; } }
- public long Interrupts { get { return endInterruptCount - begInterruptCount; } }
- public long Switches { get { return endSwitchCount - begSwitchCount; } }
- public long KernelGCs { get { return endKernelGcCount - begKernelGcCount; } }
- public long ProcessGCs { get { return endProcessGcCount - begProcessGcCount; } }
- public ulong AllocatedCount { get { return endAllocatedCount-begAllocatedCount; } }
- public ulong AllocatedBytes { get { return endAllocatedBytes-begAllocatedBytes; } }
- public ulong FreedCount { get { return endFreedCount - begFreedCount; } }
- public ulong FreedBytes { get { return endFreedBytes - begFreedBytes; } }
- public ulong StackGets { get { return endStackGets - begStackGets; } }
- public ulong StackRets { get { return endStackRets - begStackRets; } }
-
- public void Start()
- {
- if (!AtRing3) {
- disabled = Processor.DisableLocalPreemption();
- }
-
- int collectorCount;
- long collectorMillis;
- long collectorBytes;
- GC.PerformanceCounters(out collectorCount,
- out collectorMillis,
- out collectorBytes);
-
- ulong stackGets;
- ulong stackRets;
- StackService.GetUsageStatistics(out stackGets,
- out stackRets);
- begStackGets = stackGets;
- begStackRets = stackRets;
-
- ulong allocatedCount;
- ulong allocatedBytes;
- ulong freedCount;
- ulong freedBytes;
- PageTableService.GetUsageStatistics(out allocatedCount,
- out allocatedBytes,
- out freedCount,
- out freedBytes);
- begAllocatedCount = allocatedCount;
- begAllocatedBytes = allocatedBytes;
- begFreedCount = freedCount;
- begFreedBytes = freedBytes;
-
- begInterruptCount = ProcessService.GetKernelInterruptCount();
- begSwitchCount = ProcessService.GetContextSwitchCount();
- begKernelGcCount = ProcessService.GetKernelGcCount();
- begProcessGcCount = collectorCount;
-
- #if x64_PERF
- // Set up for perf counting
- if (!AtRing3) {
- // Reset the performance counters to what we're interested in.
- Reset(0, PerfEvtSel.COUNT | PerfEvtSel.CyclesNotHalted);
- Reset(1, PerfEvtSel.COUNT | PerfEvtSel.RetiredInstructions);
- Reset(2, PerfEvtSel.COUNT | PerfEvtSel.RetiredBranchInstructions);
- Reset(3, PerfEvtSel.COUNT | PerfEvtSel.RequestsToL2Cache | 0x400);
- }
- else {
- // We're not allowed to reset the perf counters, so take note
- // of their current values; we will subtract from this later.
- x64_i0 = Processor.ReadPmc(0);
- x64_i1 = Processor.ReadPmc(1);
- x64_i2 = Processor.ReadPmc(2);
- x64_i3 = Processor.ReadPmc(3);
- }
- #endif
-
- begCycleCount = unchecked((long)Processor.CycleCount);
- }
-
- public void Finish(long iterations)
- {
- endCycleCount = unchecked((long)Processor.CycleCount);
-
- #if X64_PERF
- x64_p0 = Processor.ReadPmc(0);
- x64_p1 = Processor.ReadPmc(1);
- x64_p2 = Processor.ReadPmc(2);
- x64_p3 = Processor.ReadPmc(3);
- #endif
-
- endInterruptCount = ProcessService.GetKernelInterruptCount();
- endSwitchCount = ProcessService.GetContextSwitchCount();
- endKernelGcCount = ProcessService.GetKernelGcCount();
-
- int collectorCount;
- long collectorMillis;
- long collectorBytes;
- GC.PerformanceCounters(out collectorCount,
- out collectorMillis,
- out collectorBytes);
- endProcessGcCount = collectorCount;
-
- ulong allocatedCount;
- ulong allocatedBytes;
- ulong freedCount;
- ulong freedBytes;
- PageTableService.GetUsageStatistics(out allocatedCount,
- out allocatedBytes,
- out freedCount,
- out freedBytes);
- endAllocatedCount = allocatedCount;
- endAllocatedBytes = allocatedBytes;
- endFreedCount = freedCount;
- endFreedBytes = freedBytes;
-
- ulong stackGets;
- ulong stackRets;
- StackService.GetUsageStatistics(out stackGets,
- out stackRets);
- endStackGets = stackGets;
- endStackRets = stackRets;
-
- if (!AtRing3) {
- Processor.RestoreLocalPreemption(disabled);
- }
-
- this.iterations = iterations;
- }
-
- public void Display(string name)
- {
- DualWriteLine(
- String.Format("{0,-16} {1,6:d} x{2,8:d} ={3,12:d} " +
- "[swi={4,6:d} int={5,3:d} gc={6:d}/{7:d}]",
- name,
- iterations,
- Cycles / iterations,
- Cycles,
- Switches,
- Interrupts,
- KernelGCs,
- ProcessGCs)
- );
-
-
- if (AllocatedCount != 0 || FreedCount != 0 || StackGets != 0) {
- DualWriteLine(
- string.Format(
- " " +
- "[alloc={0,4:d}/{1,8:x} free={2,4:d}/{3,8:x} " +
- "stack={4,4:d}/{5,4:d}]",
- AllocatedCount,
- AllocatedBytes,
- FreedCount,
- FreedBytes,
- StackGets,
- StackRets)
- );
- }
-
- #if x64_PERF
- if (!AtRing3) {
- // Read off the current MSR values and turn them
- // into nice labels
- ulong e0 = Processor.ReadMsr(0xc0010000);
- ulong e1 = Processor.ReadMsr(0xc0010001);
- ulong e2 = Processor.ReadMsr(0xc0010002);
- ulong e3 = Processor.ReadMsr(0xc0010003);
-
- DualWriteLine(
- String.Format("evt: {0,16} {1,16} {2,16} {3,16}",
- EvtSelToString(e0),
- EvtSelToString(e1),
- EvtSelToString(e2),
- EvtSelToString(e3)));
- }
- else {
- // Subtract from the initial perf-counter values to
- // get the delta we want
- x64_p0 -= x64_i0;
- x64_p1 -= x64_i1;
- x64_p2 -= x64_i2;
- x64_p3 -= x64_i3;
- }
-
- DualWriteLine(
- String.Format("pmc: {0:d16} {1:d16} {2:d16} {3:d16} {4:d16}\n\n",
- Cycles, x64_p0, x64_p1, x64_p2, x64_p3));
- #endif
- }
- }
-
-
- internal static int AppMain(Parameters! config)
- {
- bool runQuiet = config.quietMode;
- long repetitions = config.repetitions;
-
- Console.Write("\nProcess creation test\n\n");
- string [] arguments;
- for (long i = 0; i < repetitions; i++) {
- arguments = new string[2];
- arguments[0] = "testpe";
- arguments[1] = "!"; // Special flag to not notify debugger.
- TimeProcess(arguments, runQuiet);
- }
- return 0;
- }
-
- public static void TimeProcess(String[]! args, bool runQuiet)
- {
- ulong baseline;
- ulong created;
- ulong started;
- ulong exited;
- Process process = null;
-
- PerfSnap snap = new PerfSnap();
-
- snap.Start();
- try {
- ProcessService.Waypoint0();
- baseline = Processor.CycleCount;
-
- //
- // Time process creation.
- //
- ProcessService.Waypoint(1500);
- process = new Process(args);
- created = Processor.CycleCount;
-
- //
- // Time process start.
- //
- ProcessService.Waypoint(1501);
-
- process.Start();
- started = Processor.CycleCount;
-
- ProcessService.Waypoint(1502);
- //
- // Time process execution.
- //
- process.Join();
- ProcessService.Waypoint(1503);
- exited = Processor.CycleCount;
- }
- finally {
- snap.Finish(1);
- }
-
- snap.Display("CreateProc");
-
- ProcessService.Waypoint(1504);
- process.Dispose(true);
- ProcessService.Waypoint(1505);
- ProcessService.WaypointDump();
-
-
- if (runQuiet) {
- return;
- }
-
- //
- // Tell the world.
- //
- Console.WriteLine();
- Console.WriteLine("Tested process: {0}", args[0]);
- Console.WriteLine("Create process: {0,15:d} cycles", created - baseline);
- Console.WriteLine("Start process: {0,15:d} cycles", started - created);
- Console.WriteLine("Run process: {0,15:d} cycles", exited - started);
- Console.WriteLine("Total: {0,15:d} cycles", exited - baseline);
- Console.WriteLine("Process.Create: {0,15:d} cycles", started - baseline);
- Console.WriteLine();
- Console.WriteLine();
- }
- }
- }