xref: /xnu-8019.80.24/tests/vm/fault_throughput.lua (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
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