PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Applications/Benchmarks/CreateProcess/CreateProcess.cs

#
C# | 431 lines | 339 code | 54 blank | 38 comment | 15 complexity | d831d0fbc43dd6fc2960b218c1219342 MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Note: Singularity micro-benchmark program.
  8. //
  9. using Microsoft.Singularity;
  10. using Microsoft.Singularity.V1.Services;
  11. using Microsoft.Singularity.V1.Threads;
  12. using System;
  13. using System.Runtime.CompilerServices;
  14. using System.Diagnostics;
  15. using System.Threading;
  16. using Microsoft.Singularity.Channels;
  17. using Microsoft.Contracts;
  18. using Microsoft.SingSharp.Reflection;
  19. using Microsoft.Singularity.Applications;
  20. using Microsoft.Singularity.Io;
  21. using Microsoft.Singularity.Configuration;
  22. [assembly: Transform(typeof(ApplicationResourceTransform))]
  23. namespace Microsoft.Singularity.Applications
  24. {
  25. [ConsoleCategory(HelpMessage="CreateProcess benchmark test", DefaultAction=true)]
  26. internal class Parameters
  27. {
  28. [InputEndpoint("data")]
  29. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  30. [OutputEndpoint("data")]
  31. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  32. [BoolParameter( "q", Default=false, HelpMessage="Quiet Mode.")]
  33. internal bool quietMode;
  34. [LongParameter( "r", Default=1, HelpMessage="Repetition count.")]
  35. internal long repetitions;
  36. reflective internal Parameters();
  37. internal int AppMain() {
  38. return CreateProcessTest.AppMain(this);
  39. }
  40. }
  41. //
  42. // The goal of this test is to time how long it takes to
  43. // create a process.
  44. //
  45. public class CreateProcessTest
  46. {
  47. private static bool AtRing3;
  48. #if x64_PERF
  49. [CLSCompliant(false)]
  50. public struct PerfEvtSel
  51. {
  52. // Bits and Flags
  53. public const uint CNT_MASK = 0xff000000;
  54. public const uint INV = 0x00800000;
  55. public const uint EN = 0x00400000;
  56. public const uint INT = 0x00100000;
  57. public const uint PC = 0x00080000;
  58. public const uint E = 0x00040000;
  59. public const uint OS = 0x00020000;
  60. public const uint USR = 0x00010000;
  61. public const uint UNIT_MASK = 0x0000ff00;
  62. public const uint SELECTOR = 0x000000ff;
  63. // Common setting: Count all, but don't interrupt,
  64. public const uint COUNT = (EN | PC | OS | USR);
  65. // Selector values.
  66. public const uint DtlbL1MissL2Hit = 0x45; // Speculative
  67. public const uint DtlbL1MissL2Miss = 0x46; // Speculative
  68. public const uint CyclesNotHalted = 0x76;
  69. public const uint RequestsToL2Cache = 0x7d;
  70. public const uint ItlbL1MissL2Hit = 0x84;
  71. public const uint ItlbL1MissL2Miss = 0x85;
  72. public const uint RetiredInstructions = 0xc0;
  73. public const uint RetiredBranchInstructions = 0xc2;
  74. public const uint RetiredBranchesMispredicted = 0xc3;
  75. public const uint RetiredBranchesTaken = 0xc4;
  76. public const uint CyclesInterruptsMasked = 0xcd;
  77. public const uint CyclesInterruptsBlocked = 0xce;
  78. }
  79. public static void Reset(uint pmc, ulong value)
  80. {
  81. // Clear the event selector.
  82. Processor.WriteMsr(0xc0010000 + pmc, 0);
  83. // Clear the performance counter.
  84. Processor.WriteMsr(0xc0010004 + pmc, 0);
  85. // Enable the event selector.
  86. Processor.WriteMsr(0xc0010000 + pmc, value);
  87. }
  88. public static string EvtSelToString(ulong value)
  89. {
  90. switch (value & 0xff) {
  91. case PerfEvtSel.DtlbL1MissL2Hit: return "DTLB_L2_Hit";
  92. case PerfEvtSel.DtlbL1MissL2Miss: return "DTBL_L2_Miss";
  93. case PerfEvtSel.CyclesNotHalted: return "CyclesNotHalted";
  94. case PerfEvtSel.RequestsToL2Cache: return "TLB_L2_Requests";
  95. case PerfEvtSel.ItlbL1MissL2Hit: return "ITLB_L2_Hit";
  96. case PerfEvtSel.ItlbL1MissL2Miss: return "ITLB_L2_Miss";
  97. case PerfEvtSel.RetiredInstructions: return "Retired_Inst.";
  98. case PerfEvtSel.RetiredBranchInstructions: return "Branches";
  99. case PerfEvtSel.RetiredBranchesMispredicted:return "Br_Mispredicted";
  100. case PerfEvtSel.RetiredBranchesTaken: return "Br_Taken";
  101. case PerfEvtSel.CyclesInterruptsMasked: return "Ints_Masked (cyc)";
  102. case PerfEvtSel.CyclesInterruptsBlocked: return "Ints_Blocked (cyc)";
  103. default:
  104. return String.Format("{0:x16}", value);
  105. }
  106. }
  107. private static ulong x64_i0, x64_p0;
  108. private static ulong x64_i1, x64_p1;
  109. private static ulong x64_i2, x64_p2;
  110. private static ulong x64_i3, x64_p3;
  111. #endif
  112. private static void DualWriteLine(string message)
  113. {
  114. Console.WriteLine(message);
  115. DebugStub.WriteLine(message);
  116. }
  117. public struct PerfSnap
  118. {
  119. private bool disabled;
  120. private long begCycleCount;
  121. private long endCycleCount;
  122. private long begSwitchCount;
  123. private long endSwitchCount;
  124. private long begInterruptCount;
  125. private long endInterruptCount;
  126. private long begKernelGcCount;
  127. private long endKernelGcCount;
  128. private long begProcessGcCount;
  129. private long endProcessGcCount;
  130. private long iterations;
  131. private ulong begAllocatedCount;
  132. private ulong begAllocatedBytes;
  133. private ulong begFreedCount;
  134. private ulong begFreedBytes;
  135. private ulong endAllocatedCount;
  136. private ulong endAllocatedBytes;
  137. private ulong endFreedCount;
  138. private ulong endFreedBytes;
  139. private ulong begStackGets;
  140. private ulong begStackRets;
  141. private ulong endStackGets;
  142. private ulong endStackRets;
  143. public long Cycles { get { return endCycleCount - begCycleCount; } }
  144. public long Interrupts { get { return endInterruptCount - begInterruptCount; } }
  145. public long Switches { get { return endSwitchCount - begSwitchCount; } }
  146. public long KernelGCs { get { return endKernelGcCount - begKernelGcCount; } }
  147. public long ProcessGCs { get { return endProcessGcCount - begProcessGcCount; } }
  148. public ulong AllocatedCount { get { return endAllocatedCount-begAllocatedCount; } }
  149. public ulong AllocatedBytes { get { return endAllocatedBytes-begAllocatedBytes; } }
  150. public ulong FreedCount { get { return endFreedCount - begFreedCount; } }
  151. public ulong FreedBytes { get { return endFreedBytes - begFreedBytes; } }
  152. public ulong StackGets { get { return endStackGets - begStackGets; } }
  153. public ulong StackRets { get { return endStackRets - begStackRets; } }
  154. public void Start()
  155. {
  156. if (!AtRing3) {
  157. disabled = Processor.DisableLocalPreemption();
  158. }
  159. int collectorCount;
  160. long collectorMillis;
  161. long collectorBytes;
  162. GC.PerformanceCounters(out collectorCount,
  163. out collectorMillis,
  164. out collectorBytes);
  165. ulong stackGets;
  166. ulong stackRets;
  167. StackService.GetUsageStatistics(out stackGets,
  168. out stackRets);
  169. begStackGets = stackGets;
  170. begStackRets = stackRets;
  171. ulong allocatedCount;
  172. ulong allocatedBytes;
  173. ulong freedCount;
  174. ulong freedBytes;
  175. PageTableService.GetUsageStatistics(out allocatedCount,
  176. out allocatedBytes,
  177. out freedCount,
  178. out freedBytes);
  179. begAllocatedCount = allocatedCount;
  180. begAllocatedBytes = allocatedBytes;
  181. begFreedCount = freedCount;
  182. begFreedBytes = freedBytes;
  183. begInterruptCount = ProcessService.GetKernelInterruptCount();
  184. begSwitchCount = ProcessService.GetContextSwitchCount();
  185. begKernelGcCount = ProcessService.GetKernelGcCount();
  186. begProcessGcCount = collectorCount;
  187. #if x64_PERF
  188. // Set up for perf counting
  189. if (!AtRing3) {
  190. // Reset the performance counters to what we're interested in.
  191. Reset(0, PerfEvtSel.COUNT | PerfEvtSel.CyclesNotHalted);
  192. Reset(1, PerfEvtSel.COUNT | PerfEvtSel.RetiredInstructions);
  193. Reset(2, PerfEvtSel.COUNT | PerfEvtSel.RetiredBranchInstructions);
  194. Reset(3, PerfEvtSel.COUNT | PerfEvtSel.RequestsToL2Cache | 0x400);
  195. }
  196. else {
  197. // We're not allowed to reset the perf counters, so take note
  198. // of their current values; we will subtract from this later.
  199. x64_i0 = Processor.ReadPmc(0);
  200. x64_i1 = Processor.ReadPmc(1);
  201. x64_i2 = Processor.ReadPmc(2);
  202. x64_i3 = Processor.ReadPmc(3);
  203. }
  204. #endif
  205. begCycleCount = unchecked((long)Processor.CycleCount);
  206. }
  207. public void Finish(long iterations)
  208. {
  209. endCycleCount = unchecked((long)Processor.CycleCount);
  210. #if X64_PERF
  211. x64_p0 = Processor.ReadPmc(0);
  212. x64_p1 = Processor.ReadPmc(1);
  213. x64_p2 = Processor.ReadPmc(2);
  214. x64_p3 = Processor.ReadPmc(3);
  215. #endif
  216. endInterruptCount = ProcessService.GetKernelInterruptCount();
  217. endSwitchCount = ProcessService.GetContextSwitchCount();
  218. endKernelGcCount = ProcessService.GetKernelGcCount();
  219. int collectorCount;
  220. long collectorMillis;
  221. long collectorBytes;
  222. GC.PerformanceCounters(out collectorCount,
  223. out collectorMillis,
  224. out collectorBytes);
  225. endProcessGcCount = collectorCount;
  226. ulong allocatedCount;
  227. ulong allocatedBytes;
  228. ulong freedCount;
  229. ulong freedBytes;
  230. PageTableService.GetUsageStatistics(out allocatedCount,
  231. out allocatedBytes,
  232. out freedCount,
  233. out freedBytes);
  234. endAllocatedCount = allocatedCount;
  235. endAllocatedBytes = allocatedBytes;
  236. endFreedCount = freedCount;
  237. endFreedBytes = freedBytes;
  238. ulong stackGets;
  239. ulong stackRets;
  240. StackService.GetUsageStatistics(out stackGets,
  241. out stackRets);
  242. endStackGets = stackGets;
  243. endStackRets = stackRets;
  244. if (!AtRing3) {
  245. Processor.RestoreLocalPreemption(disabled);
  246. }
  247. this.iterations = iterations;
  248. }
  249. public void Display(string name)
  250. {
  251. DualWriteLine(
  252. String.Format("{0,-16} {1,6:d} x{2,8:d} ={3,12:d} " +
  253. "[swi={4,6:d} int={5,3:d} gc={6:d}/{7:d}]",
  254. name,
  255. iterations,
  256. Cycles / iterations,
  257. Cycles,
  258. Switches,
  259. Interrupts,
  260. KernelGCs,
  261. ProcessGCs)
  262. );
  263. if (AllocatedCount != 0 || FreedCount != 0 || StackGets != 0) {
  264. DualWriteLine(
  265. string.Format(
  266. " " +
  267. "[alloc={0,4:d}/{1,8:x} free={2,4:d}/{3,8:x} " +
  268. "stack={4,4:d}/{5,4:d}]",
  269. AllocatedCount,
  270. AllocatedBytes,
  271. FreedCount,
  272. FreedBytes,
  273. StackGets,
  274. StackRets)
  275. );
  276. }
  277. #if x64_PERF
  278. if (!AtRing3) {
  279. // Read off the current MSR values and turn them
  280. // into nice labels
  281. ulong e0 = Processor.ReadMsr(0xc0010000);
  282. ulong e1 = Processor.ReadMsr(0xc0010001);
  283. ulong e2 = Processor.ReadMsr(0xc0010002);
  284. ulong e3 = Processor.ReadMsr(0xc0010003);
  285. DualWriteLine(
  286. String.Format("evt: {0,16} {1,16} {2,16} {3,16}",
  287. EvtSelToString(e0),
  288. EvtSelToString(e1),
  289. EvtSelToString(e2),
  290. EvtSelToString(e3)));
  291. }
  292. else {
  293. // Subtract from the initial perf-counter values to
  294. // get the delta we want
  295. x64_p0 -= x64_i0;
  296. x64_p1 -= x64_i1;
  297. x64_p2 -= x64_i2;
  298. x64_p3 -= x64_i3;
  299. }
  300. DualWriteLine(
  301. String.Format("pmc: {0:d16} {1:d16} {2:d16} {3:d16} {4:d16}\n\n",
  302. Cycles, x64_p0, x64_p1, x64_p2, x64_p3));
  303. #endif
  304. }
  305. }
  306. internal static int AppMain(Parameters! config)
  307. {
  308. bool runQuiet = config.quietMode;
  309. long repetitions = config.repetitions;
  310. Console.Write("\nProcess creation test\n\n");
  311. string [] arguments;
  312. for (long i = 0; i < repetitions; i++) {
  313. arguments = new string[2];
  314. arguments[0] = "testpe";
  315. arguments[1] = "!"; // Special flag to not notify debugger.
  316. TimeProcess(arguments, runQuiet);
  317. }
  318. return 0;
  319. }
  320. public static void TimeProcess(String[]! args, bool runQuiet)
  321. {
  322. ulong baseline;
  323. ulong created;
  324. ulong started;
  325. ulong exited;
  326. Process process = null;
  327. PerfSnap snap = new PerfSnap();
  328. snap.Start();
  329. try {
  330. ProcessService.Waypoint0();
  331. baseline = Processor.CycleCount;
  332. //
  333. // Time process creation.
  334. //
  335. ProcessService.Waypoint(1500);
  336. process = new Process(args);
  337. created = Processor.CycleCount;
  338. //
  339. // Time process start.
  340. //
  341. ProcessService.Waypoint(1501);
  342. process.Start();
  343. started = Processor.CycleCount;
  344. ProcessService.Waypoint(1502);
  345. //
  346. // Time process execution.
  347. //
  348. process.Join();
  349. ProcessService.Waypoint(1503);
  350. exited = Processor.CycleCount;
  351. }
  352. finally {
  353. snap.Finish(1);
  354. }
  355. snap.Display("CreateProc");
  356. ProcessService.Waypoint(1504);
  357. process.Dispose(true);
  358. ProcessService.Waypoint(1505);
  359. ProcessService.WaypointDump();
  360. if (runQuiet) {
  361. return;
  362. }
  363. //
  364. // Tell the world.
  365. //
  366. Console.WriteLine();
  367. Console.WriteLine("Tested process: {0}", args[0]);
  368. Console.WriteLine("Create process: {0,15:d} cycles", created - baseline);
  369. Console.WriteLine("Start process: {0,15:d} cycles", started - created);
  370. Console.WriteLine("Run process: {0,15:d} cycles", exited - started);
  371. Console.WriteLine("Total: {0,15:d} cycles", exited - baseline);
  372. Console.WriteLine("Process.Create: {0,15:d} cycles", started - baseline);
  373. Console.WriteLine();
  374. Console.WriteLine();
  375. }
  376. }
  377. }