1*a325d9c4SApple OSS Distributions#!/usr/local/bin/recon 2*a325d9c4SApple OSS Distributionsrequire 'strict' 3*a325d9c4SApple OSS Distributions 4*a325d9c4SApple OSS Distributionslocal benchrun = require 'benchrun' 5*a325d9c4SApple OSS Distributionslocal perfdata = require 'perfdata' 6*a325d9c4SApple OSS Distributionslocal csv = require 'csv' 7*a325d9c4SApple OSS Distributionslocal sysctl = require 'sysctl' 8*a325d9c4SApple OSS Distributionslocal os = require 'os' 9*a325d9c4SApple OSS Distributions 10*a325d9c4SApple OSS Distributionslocal kDefaultDuration = 30 11*a325d9c4SApple OSS Distributions 12*a325d9c4SApple OSS Distributionslocal benchmark = benchrun.new { 13*a325d9c4SApple OSS Distributions name = 'xnu.zero_fill_fault_throughput', 14*a325d9c4SApple OSS Distributions version = 1, 15*a325d9c4SApple OSS Distributions arg = arg, 16*a325d9c4SApple OSS Distributions modify_argparser = function(parser) 17*a325d9c4SApple OSS Distributions parser:option{ 18*a325d9c4SApple OSS Distributions name = '--cpu-workers', 19*a325d9c4SApple OSS Distributions description = 'Number of cpu workers' 20*a325d9c4SApple OSS Distributions } 21*a325d9c4SApple OSS Distributions parser:flag{ 22*a325d9c4SApple OSS Distributions name = '--through-max-workers', 23*a325d9c4SApple OSS Distributions description = 'Run benchmark for [1..n] cpu workers' 24*a325d9c4SApple OSS Distributions } 25*a325d9c4SApple OSS Distributions parser:flag{ 26*a325d9c4SApple OSS Distributions name = '--through-max-workers-fast', 27*a325d9c4SApple OSS Distributions description = 'Run benchmark for [1..2] and each power of four value in [4..n] cpu workers' 28*a325d9c4SApple OSS Distributions } 29*a325d9c4SApple OSS Distributions parser:option{ 30*a325d9c4SApple OSS Distributions name = '--path', 31*a325d9c4SApple OSS Distributions description = 'Path to fault throughput binary' 32*a325d9c4SApple OSS Distributions } 33*a325d9c4SApple OSS Distributions parser:option{ 34*a325d9c4SApple OSS Distributions name = '--duration', 35*a325d9c4SApple OSS Distributions description = 'How long, in seconds, to run each iteration', 36*a325d9c4SApple OSS Distributions default = kDefaultDuration 37*a325d9c4SApple OSS Distributions } 38*a325d9c4SApple OSS Distributions parser:option{ 39*a325d9c4SApple OSS Distributions name = '--variant', 40*a325d9c4SApple OSS Distributions description = 'Which benchmark variant to run (sparate-objects or share-objects)', 41*a325d9c4SApple OSS Distributions default = 'separate-objects' 42*a325d9c4SApple OSS Distributions } 43*a325d9c4SApple OSS Distributions parser:option{ 44*a325d9c4SApple OSS Distributions name = '--first-cpu', 45*a325d9c4SApple OSS Distributions description = 'Enable thread pinning starting from this CPU ID. "enable_skstb=1" boot-arg required', 46*a325d9c4SApple OSS Distributions default = -1 47*a325d9c4SApple OSS Distributions } 48*a325d9c4SApple OSS Distributions end 49*a325d9c4SApple OSS Distributions} 50*a325d9c4SApple OSS Distributions 51*a325d9c4SApple OSS Distributionsassert(benchmark.opt.path, "No path supplied for fault throughput binary") 52*a325d9c4SApple OSS Distributionsassert(benchmark.opt.variant == "separate-objects" or 53*a325d9c4SApple OSS Distributions benchmark.opt.variant == "share-objects", "Unsupported benchmark variant") 54*a325d9c4SApple OSS Distributions 55*a325d9c4SApple OSS Distributionslocal ncpus, err = sysctl('hw.logicalcpu_max') 56*a325d9c4SApple OSS Distributionsassert(ncpus > 0, 'invalid number of logical cpus') 57*a325d9c4SApple OSS Distributionslocal cpu_workers = tonumber(benchmark.opt.cpu_workers) or ncpus 58*a325d9c4SApple OSS Distributions 59*a325d9c4SApple OSS Distributionsassert(tonumber(benchmark.opt.first_cpu) < ncpus, "invalid first CPU") 60*a325d9c4SApple OSS Distributions 61*a325d9c4SApple OSS Distributionslocal unit = perfdata.unit.custom('pages/sec') 62*a325d9c4SApple OSS Distributionslocal tests = {} 63*a325d9c4SApple OSS Distributions 64*a325d9c4SApple OSS Distributionsfunction QueueTest(num_cores) 65*a325d9c4SApple OSS Distributions table.insert(tests, { 66*a325d9c4SApple OSS Distributions path = benchmark.opt.path, 67*a325d9c4SApple OSS Distributions num_cores = num_cores, 68*a325d9c4SApple OSS Distributions }) 69*a325d9c4SApple OSS Distributionsend 70*a325d9c4SApple OSS Distributions 71*a325d9c4SApple OSS Distributionsif benchmark.opt.through_max_workers then 72*a325d9c4SApple OSS Distributions for i = 1, cpu_workers do 73*a325d9c4SApple OSS Distributions QueueTest(i) 74*a325d9c4SApple OSS Distributions end 75*a325d9c4SApple OSS Distributionselseif benchmark.opt.through_max_workers_fast then 76*a325d9c4SApple OSS Distributions local i = 1 77*a325d9c4SApple OSS Distributions while i <= cpu_workers do 78*a325d9c4SApple OSS Distributions QueueTest(i) 79*a325d9c4SApple OSS Distributions -- Always do a run with two threads to see what the first part of 80*a325d9c4SApple OSS Distributions -- the scaling curve looks like 81*a325d9c4SApple OSS Distributions -- (and to measure perf on dual core systems). 82*a325d9c4SApple OSS Distributions if i == 1 and cpu_workers >= 2 then 83*a325d9c4SApple OSS Distributions QueueTest(i + 1) 84*a325d9c4SApple OSS Distributions end 85*a325d9c4SApple OSS Distributions i = i * 4 86*a325d9c4SApple OSS Distributions end 87*a325d9c4SApple OSS Distributionselse 88*a325d9c4SApple OSS Distributions QueueTest(cpu_workers) 89*a325d9c4SApple OSS Distributionsend 90*a325d9c4SApple OSS Distributions 91*a325d9c4SApple OSS Distributionsfor _, test in ipairs(tests) do 92*a325d9c4SApple OSS Distributions local args = {test.path, "-v", benchmark.opt.variant, benchmark.opt.duration, test.num_cores, 93*a325d9c4SApple OSS Distributions echo = true} 94*a325d9c4SApple OSS Distributions if benchmark.opt.first_cpu ~= -1 then 95*a325d9c4SApple OSS Distributions args[#args + 1] = benchmark.opt.first_cpu 96*a325d9c4SApple OSS Distributions end 97*a325d9c4SApple OSS Distributions for out in benchmark:run(args) do 98*a325d9c4SApple OSS Distributions local result = out:match("-----Results-----\n(.*)") 99*a325d9c4SApple OSS Distributions benchmark:assert(result, "Unable to find result data in output") 100*a325d9c4SApple OSS Distributions local data = csv.openstring(result, {header = true}) 101*a325d9c4SApple OSS Distributions for field in data:lines() do 102*a325d9c4SApple OSS Distributions for k, v in pairs(field) do 103*a325d9c4SApple OSS Distributions benchmark.writer:add_value(k, unit, tonumber(v), { 104*a325d9c4SApple OSS Distributions [perfdata.larger_better] = true, 105*a325d9c4SApple OSS Distributions threads = test.num_cores, 106*a325d9c4SApple OSS Distributions variant = benchmark.opt.variant 107*a325d9c4SApple OSS Distributions }) 108*a325d9c4SApple OSS Distributions end 109*a325d9c4SApple OSS Distributions end 110*a325d9c4SApple OSS Distributions end 111*a325d9c4SApple OSS Distributionsend 112*a325d9c4SApple OSS Distributions 113*a325d9c4SApple OSS Distributionsbenchmark:finish() 114