shell-bench.js (4184B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 var FPS = 60; 6 var gNumSamples = 500; 7 8 // This requires a gHost to have been created that provides host-specific 9 // facilities. See eg spidermonkey.js. 10 11 loadRelativeToScript("argparse.js"); 12 loadRelativeToScript("harness.js"); 13 loadRelativeToScript("sequencer.js"); 14 loadRelativeToScript("scheduler.js"); 15 loadRelativeToScript("perf.js"); 16 loadRelativeToScript("test_list.js"); 17 18 var gPerf = new PerfTracker(); 19 20 var tests = new Map(); 21 foreach_test_file(f => loadRelativeToScript(f)); 22 for (const [name, info] of tests.entries()) { 23 if ("enabled" in info && !info.enabled) { 24 tests.delete(name); 25 } 26 } 27 28 function tick(loadMgr, timestamp) { 29 gPerf.before_mutator(timestamp); 30 gHost.start_turn(); 31 const events = loadMgr.tick(timestamp); 32 gHost.end_turn(); 33 gPerf.after_mutator(timestamp); 34 return events; 35 } 36 37 function run(opts, loads) { 38 const sequence = []; 39 for (const mut of loads) { 40 if (tests.has(mut)) { 41 sequence.push(mut); 42 } else if (mut === "all") { 43 sequence.push(...tests.keys()); 44 } else { 45 sequence.push(...[...tests.keys()].filter(t => t.includes(mut))); 46 } 47 } 48 if (loads.length === 0) { 49 sequence.push(...tests.keys()); 50 } 51 52 const loadMgr = new AllocationLoadManager(tests); 53 const perf = new FrameHistory(gNumSamples); 54 55 const mutators = sequence.map(name => new SingleMutatorSequencer(loadMgr.getByName(name), gPerf, opts.duration)); 56 let sequencer; 57 if (opts.sequencer == 'cycle') { 58 sequencer = new ChainSequencer(mutators); 59 } else if (opts.sequencer == 'find50') { 60 const seekers = mutators.map(s => new Find50Sequencer(s, loadMgr)); 61 sequencer = new ChainSequencer(seekers); 62 } 63 64 const schedulerCtors = { 65 keepup: OptimizeForFrameRate, 66 vsync: VsyncScheduler, 67 }; 68 const scheduler = new schedulerCtors[opts.sched](gPerf); 69 70 perf.start(); 71 72 const t0 = gHost.now(); 73 74 let possible = 0; 75 let frames = 0; 76 loadMgr.startSequencer(sequencer); 77 print(`${loadMgr.activeLoad().name} starting`); 78 while (loadMgr.load_running()) { 79 const timestamp = gHost.now(); 80 const completed = scheduler.tick(loadMgr, timestamp); 81 const after_tick = gHost.now(); 82 83 perf.on_frame(timestamp); 84 85 if (completed) { 86 print(`${loadMgr.lastActive.name} ended`); 87 if (loadMgr.load_running()) { 88 print(`${loadMgr.activeLoad().name} starting`); 89 } 90 } 91 92 frames++; 93 if (completed) { 94 possible += (loadMgr.testDurationMS / 1000) * FPS; 95 const elapsed = ((after_tick - t0) / 1000).toFixed(2); 96 print(` observed ${frames} / ${possible} frames in ${elapsed} seconds`); 97 } 98 99 scheduler.wait_for_next_frame(t0, timestamp, after_tick); 100 } 101 } 102 103 function report_results() { 104 for (const result of gPerf.results) { 105 const { 106 load, 107 elapsed_time, 108 mutating, 109 mutating_and_gc_fraction, 110 suspended, 111 full_time, 112 frames, 113 dropped_60fps_frames, 114 dropped_60fps_fraction, 115 minorGCs, 116 majorGCs, 117 } = result; 118 119 const drop_pct = percent(dropped_60fps_fraction); 120 const mut_pct = percent(mutating_and_gc_fraction); 121 const mut_sec = mutating.toFixed(2); 122 const full_sec = full_time.toFixed(2); 123 const susp_sec = suspended.toFixed(2); 124 print(`${load.name}: 125 ${frames} (60fps) frames seen out of expected ${Math.floor(full_time * 60)} 126 ${dropped_60fps_frames} = ${drop_pct} 60fps frames dropped 127 ${mut_pct} of run spent mutating and GCing (${mut_sec}sec out of ${full_sec}sec vs ${susp_sec} sec waiting) 128 ${minorGCs} minor GCs, ${majorGCs} major GCs 129 `); 130 } 131 } 132 133 var argparse = new ArgParser("JS shell microbenchmark runner"); 134 argparse.add_argument(["--duration", "-d"], { 135 default: gDefaultTestDuration, 136 help: "how long to run mutators for (in seconds)" 137 }); 138 argparse.add_argument("--sched", { 139 default: "keepup", 140 options: ["keepup", "vsync"], 141 help: "frame scheduler" 142 }); 143 argparse.add_argument("--sequencer", { 144 default: "cycle", 145 options: ["cycle", "find50"], 146 help: "mutator sequencer" 147 });