xref: /xnu-11215.1.10/tests/vm/fault_throughput.lua (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
1*8d741a5dSApple OSS Distributions#!/usr/local/bin/recon
2*8d741a5dSApple OSS Distributions
3*8d741a5dSApple OSS Distributionslocal benchrun = require 'benchrun'
4*8d741a5dSApple OSS Distributionslocal csv = require 'csv'
5*8d741a5dSApple OSS Distributionslocal os = require 'os'
6*8d741a5dSApple OSS Distributionslocal perfdata = require 'perfdata'
7*8d741a5dSApple OSS Distributionslocal sysctl = require 'sysctl'
8*8d741a5dSApple OSS Distributions
9*8d741a5dSApple OSS Distributionsrequire 'strict'
10*8d741a5dSApple OSS Distributions
11*8d741a5dSApple OSS Distributionslocal benchmark = benchrun.new({
12*8d741a5dSApple OSS Distributions  name = 'xnu.zero_fill_fault_throughput',
13*8d741a5dSApple OSS Distributions  version = 1,
14*8d741a5dSApple OSS Distributions  arg = arg,
15*8d741a5dSApple OSS Distributions  modify_argparser = function(parser)
16*8d741a5dSApple OSS Distributions    parser:option{
17*8d741a5dSApple OSS Distributions      name = '--cpu-workers',
18*8d741a5dSApple OSS Distributions      description = 'Number of threads to bring up to do faulting work',
19*8d741a5dSApple OSS Distributions      convert = tonumber,
20*8d741a5dSApple OSS Distributions      argname = 'count',
21*8d741a5dSApple OSS Distributions    }
22*8d741a5dSApple OSS Distributions    parser:flag{
23*8d741a5dSApple OSS Distributions      name = '--through-max-workers',
24*8d741a5dSApple OSS Distributions      description = 'Run with [1..n] CPU workers',
25*8d741a5dSApple OSS Distributions    }
26*8d741a5dSApple OSS Distributions    parser:flag{
27*8d741a5dSApple OSS Distributions      name = '--through-max-workers-fast',
28*8d741a5dSApple OSS Distributions      description = 'Run with 1, 2, and each power of four value in [4..n] CPU workers',
29*8d741a5dSApple OSS Distributions    }
30*8d741a5dSApple OSS Distributions    parser:option{
31*8d741a5dSApple OSS Distributions      name = '--path',
32*8d741a5dSApple OSS Distributions      description = 'Path to fault throughput binary',
33*8d741a5dSApple OSS Distributions      count = 1, -- This is a required option.
34*8d741a5dSApple OSS Distributions    }
35*8d741a5dSApple OSS Distributions    parser:option{
36*8d741a5dSApple OSS Distributions      name = '--duration',
37*8d741a5dSApple OSS Distributions      description = 'How long, in seconds, to run each iteration',
38*8d741a5dSApple OSS Distributions      default = 30,
39*8d741a5dSApple OSS Distributions      convert = tonumber,
40*8d741a5dSApple OSS Distributions      argname = 'seconds',
41*8d741a5dSApple OSS Distributions    }
42*8d741a5dSApple OSS Distributions    parser:option{
43*8d741a5dSApple OSS Distributions      name = '--variant',
44*8d741a5dSApple OSS Distributions      description = 'Which benchmark variant to run',
45*8d741a5dSApple OSS Distributions      choices = { 'separate-objects', 'share-objects' },
46*8d741a5dSApple OSS Distributions      default = 'separate-objects',
47*8d741a5dSApple OSS Distributions      argname = 'name',
48*8d741a5dSApple OSS Distributions    }
49*8d741a5dSApple OSS Distributions    parser:option{
50*8d741a5dSApple OSS Distributions      name = '--first-cpu',
51*8d741a5dSApple OSS Distributions      description = 'Pin threads to CPUs, starting with this CPU ID; requires enable_skstb=1 boot-arg',
52*8d741a5dSApple OSS Distributions      default = -1,
53*8d741a5dSApple OSS Distributions      convert = tonumber,
54*8d741a5dSApple OSS Distributions      argname = 'cpu-id'
55*8d741a5dSApple OSS Distributions    }
56*8d741a5dSApple OSS Distributions    parser:flag{
57*8d741a5dSApple OSS Distributions      name = '--verbose',
58*8d741a5dSApple OSS Distributions      description = 'Enable verbose logging at a performance cost',
59*8d741a5dSApple OSS Distributions    }
60*8d741a5dSApple OSS Distributions  end,
61*8d741a5dSApple OSS Distributions})
62*8d741a5dSApple OSS Distributions
63*8d741a5dSApple OSS Distributionslocal ncpus, _ = sysctl('hw.logicalcpu_max')
64*8d741a5dSApple OSS Distributionsbenchmark:assert(ncpus > 0, 'invalid number of logical CPUs')
65*8d741a5dSApple OSS Distributionslocal cpu_workers = benchmark.opt.cpu_workers or ncpus
66*8d741a5dSApple OSS Distributionsbenchmark:assert(cpu_workers > 0, 'invalid number of CPU workers')
67*8d741a5dSApple OSS Distributions
68*8d741a5dSApple OSS Distributionsbenchmark:assert(benchmark.opt.first_cpu > -2, 'negative first CPU')
69*8d741a5dSApple OSS Distributionsbenchmark:assert(benchmark.opt.first_cpu < ncpus, 'invalid first CPU')
70*8d741a5dSApple OSS Distributions
71*8d741a5dSApple OSS Distributionslocal page_throughput_unit = perfdata.unit.custom('pages/sec')
72*8d741a5dSApple OSS Distributions
73*8d741a5dSApple OSS Distributionslocal test_threads = {}
74*8d741a5dSApple OSS Distributions
75*8d741a5dSApple OSS Distributionsif benchmark.opt.through_max_workers then
76*8d741a5dSApple OSS Distributions  for i = 1, cpu_workers do
77*8d741a5dSApple OSS Distributions    table.insert(test_threads, i)
78*8d741a5dSApple OSS Distributions  end
79*8d741a5dSApple OSS Distributionselseif benchmark.opt.through_max_workers_fast then
80*8d741a5dSApple OSS Distributions  local i = 1
81*8d741a5dSApple OSS Distributions  while i <= cpu_workers do
82*8d741a5dSApple OSS Distributions    table.insert(test_threads, i)
83*8d741a5dSApple OSS Distributions    -- Always do a run with two threads to see what the first part of the
84*8d741a5dSApple OSS Distributions    -- scaling curve looks like (and to measure perf on dual core systems).
85*8d741a5dSApple OSS Distributions    if i == 1 and cpu_workers >= 2 then
86*8d741a5dSApple OSS Distributions      table.insert(test_threads, i + 1)
87*8d741a5dSApple OSS Distributions    end
88*8d741a5dSApple OSS Distributions    i = i * 4
89*8d741a5dSApple OSS Distributions  end
90*8d741a5dSApple OSS Distributionselse
91*8d741a5dSApple OSS Distributions  table.insert(test_threads, cpu_workers)
92*8d741a5dSApple OSS Distributionsend
93*8d741a5dSApple OSS Distributions
94*8d741a5dSApple OSS Distributionsfor _, thread_count in ipairs(test_threads) do
95*8d741a5dSApple OSS Distributions  local cmd = {
96*8d741a5dSApple OSS Distributions    benchmark.opt.path;
97*8d741a5dSApple OSS Distributions    echo = true,
98*8d741a5dSApple OSS Distributions    name = ('with %d CPU workers%s'):format(thread_count,
99*8d741a5dSApple OSS Distributions        thread_count == 1 and '' or 's'),
100*8d741a5dSApple OSS Distributions  }
101*8d741a5dSApple OSS Distributions  if benchmark.opt.verbose then
102*8d741a5dSApple OSS Distributions    cmd[#cmd + 1] = '-v'
103*8d741a5dSApple OSS Distributions  end
104*8d741a5dSApple OSS Distributions  cmd[#cmd + 1] = benchmark.opt.variant
105*8d741a5dSApple OSS Distributions  cmd[#cmd + 1] = benchmark.opt.duration
106*8d741a5dSApple OSS Distributions  cmd[#cmd + 1] = thread_count
107*8d741a5dSApple OSS Distributions  if benchmark.opt.first_cpu ~= -1 then
108*8d741a5dSApple OSS Distributions    cmd[#cmd + 1] = benchmark.opt.first_cpu
109*8d741a5dSApple OSS Distributions  end
110*8d741a5dSApple OSS Distributions
111*8d741a5dSApple OSS Distributions  for out in benchmark:run(cmd) do
112*8d741a5dSApple OSS Distributions    local result = out:match('-----Results-----\n(.*)')
113*8d741a5dSApple OSS Distributions    benchmark:assert(result, 'unable to find result data in output')
114*8d741a5dSApple OSS Distributions    local data = csv.openstring(result, { header = true })
115*8d741a5dSApple OSS Distributions    for field in data:lines() do
116*8d741a5dSApple OSS Distributions      for k, v in pairs(field) do
117*8d741a5dSApple OSS Distributions        benchmark.writer:add_value(k, page_throughput_unit, tonumber(v), {
118*8d741a5dSApple OSS Distributions          [perfdata.larger_better] = true,
119*8d741a5dSApple OSS Distributions          threads = thread_count,
120*8d741a5dSApple OSS Distributions          variant = benchmark.opt.variant
121*8d741a5dSApple OSS Distributions        })
122*8d741a5dSApple OSS Distributions      end
123*8d741a5dSApple OSS Distributions    end
124*8d741a5dSApple OSS Distributions  end
125*8d741a5dSApple OSS Distributionsend
126*8d741a5dSApple OSS Distributions
127*8d741a5dSApple OSS Distributionsbenchmark:finish()
128