xref: /xnu-11215.1.10/tests/counter/benchmark.lua (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
1*8d741a5dSApple OSS Distributions#!/usr/local/bin/recon
2*8d741a5dSApple OSS Distributionsrequire 'strict'
3*8d741a5dSApple OSS Distributions
4*8d741a5dSApple OSS Distributionslocal benchrun = require 'benchrun'
5*8d741a5dSApple OSS Distributionslocal perfdata = require 'perfdata'
6*8d741a5dSApple OSS Distributionslocal sysctl = require 'sysctl'
7*8d741a5dSApple OSS Distributionslocal csv = require 'csv'
8*8d741a5dSApple OSS Distributions
9*8d741a5dSApple OSS Distributionslocal kDefaultNumWrites = 10000000000
10*8d741a5dSApple OSS Distributions
11*8d741a5dSApple OSS Distributionslocal benchmark = benchrun.new {
12*8d741a5dSApple OSS Distributions    name = 'xnu.per_cpu_counter',
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:argument{
17*8d741a5dSApple OSS Distributions          name = 'path',
18*8d741a5dSApple OSS Distributions          description = 'Path to benchmark binary'
19*8d741a5dSApple OSS Distributions        }
20*8d741a5dSApple OSS Distributions        parser:option{
21*8d741a5dSApple OSS Distributions            name = '--cpu-workers',
22*8d741a5dSApple OSS Distributions            description = 'Number of cpu workers'
23*8d741a5dSApple OSS Distributions        }
24*8d741a5dSApple OSS Distributions        parser:flag{
25*8d741a5dSApple OSS Distributions          name = '--through-max-workers',
26*8d741a5dSApple OSS Distributions          description = 'Run benchmark for [1..n] cpu workers'
27*8d741a5dSApple OSS Distributions        }
28*8d741a5dSApple OSS Distributions        parser:flag{
29*8d741a5dSApple OSS Distributions          name = '--through-max-workers-fast',
30*8d741a5dSApple OSS Distributions          description = 'Run benchmark for [1..2] and each power of four value in [4..n] cpu workers'
31*8d741a5dSApple OSS Distributions        }
32*8d741a5dSApple OSS Distributions        parser:option {
33*8d741a5dSApple OSS Distributions            name = "--num-writes",
34*8d741a5dSApple OSS Distributions            description = "number of writes",
35*8d741a5dSApple OSS Distributions            default = kDefaultNumWrites
36*8d741a5dSApple OSS Distributions        }
37*8d741a5dSApple OSS Distributions        parser:option{
38*8d741a5dSApple OSS Distributions            name = '--variant',
39*8d741a5dSApple OSS Distributions            description = 'Which benchmark variant to run (scalable, atomic, or racy)',
40*8d741a5dSApple OSS Distributions            default = 'scalable',
41*8d741a5dSApple OSS Distributions            choices = {"scalable", "atomic", "racy"}
42*8d741a5dSApple OSS Distributions        }
43*8d741a5dSApple OSS Distributions    end
44*8d741a5dSApple OSS Distributions}
45*8d741a5dSApple OSS Distributions
46*8d741a5dSApple OSS Distributionsassert(benchmark.opt.path, "No path supplied for fault throughput binary")
47*8d741a5dSApple OSS Distributions
48*8d741a5dSApple OSS Distributionslocal ncpus, err = sysctl('hw.logicalcpu_max')
49*8d741a5dSApple OSS Distributionsassert(ncpus > 0, 'invalid number of logical cpus')
50*8d741a5dSApple OSS Distributionslocal cpu_workers = tonumber(benchmark.opt.cpu_workers) or ncpus
51*8d741a5dSApple OSS Distributions
52*8d741a5dSApple OSS Distributionslocal writes_per_second = perfdata.unit.custom('writes/sec')
53*8d741a5dSApple OSS Distributionslocal tests = {}
54*8d741a5dSApple OSS Distributions
55*8d741a5dSApple OSS Distributionsfunction QueueTest(num_cores)
56*8d741a5dSApple OSS Distributions    table.insert(tests, {
57*8d741a5dSApple OSS Distributions        path = benchmark.opt.path,
58*8d741a5dSApple OSS Distributions        num_cores = num_cores,
59*8d741a5dSApple OSS Distributions    })
60*8d741a5dSApple OSS Distributionsend
61*8d741a5dSApple OSS Distributions
62*8d741a5dSApple OSS Distributionsif benchmark.opt.through_max_workers then
63*8d741a5dSApple OSS Distributions    for i = 1, cpu_workers do
64*8d741a5dSApple OSS Distributions        QueueTest(i)
65*8d741a5dSApple OSS Distributions    end
66*8d741a5dSApple OSS Distributionselseif benchmark.opt.through_max_workers_fast then
67*8d741a5dSApple OSS Distributions    local i = 1
68*8d741a5dSApple OSS Distributions    while i <= cpu_workers do
69*8d741a5dSApple OSS Distributions        QueueTest(i)
70*8d741a5dSApple OSS Distributions        -- Always do a run with two threads to see what the first part of
71*8d741a5dSApple OSS Distributions        -- the scaling curve looks like
72*8d741a5dSApple OSS Distributions        -- (and to measure perf on dual core systems).
73*8d741a5dSApple OSS Distributions        if i == 1 and cpu_workers >= 2 then
74*8d741a5dSApple OSS Distributions            QueueTest(i + 1)
75*8d741a5dSApple OSS Distributions        end
76*8d741a5dSApple OSS Distributions        i = i * 4
77*8d741a5dSApple OSS Distributions    end
78*8d741a5dSApple OSS Distributionselse
79*8d741a5dSApple OSS Distributions    QueueTest(cpu_workers)
80*8d741a5dSApple OSS Distributionsend
81*8d741a5dSApple OSS Distributions
82*8d741a5dSApple OSS Distributionsfor _, test in ipairs(tests) do
83*8d741a5dSApple OSS Distributions    local args = {test.path, benchmark.opt.variant, benchmark.opt.num_writes, test.num_cores,
84*8d741a5dSApple OSS Distributions                     echo = true}
85*8d741a5dSApple OSS Distributions    for out in benchmark:run(args) do
86*8d741a5dSApple OSS Distributions        local result = out:match("-----Results-----\n(.*)")
87*8d741a5dSApple OSS Distributions        benchmark:assert(result, "Unable to find result data in output")
88*8d741a5dSApple OSS Distributions        local data = csv.openstring(result, {header = true})
89*8d741a5dSApple OSS Distributions        for field in data:lines() do
90*8d741a5dSApple OSS Distributions            for k, v in pairs(field) do
91*8d741a5dSApple OSS Distributions                local unit = writes_per_second
92*8d741a5dSApple OSS Distributions                local larger_better = true
93*8d741a5dSApple OSS Distributions                if k == "loss" then
94*8d741a5dSApple OSS Distributions                    unit = percentage
95*8d741a5dSApple OSS Distributions                    larger_better = false
96*8d741a5dSApple OSS Distributions                end
97*8d741a5dSApple OSS Distributions                benchmark.writer:add_value(k, unit, tonumber(v), {
98*8d741a5dSApple OSS Distributions                  [perfdata.larger_better] = larger_better,
99*8d741a5dSApple OSS Distributions                  threads = test.num_cores,
100*8d741a5dSApple OSS Distributions                  variant = benchmark.opt.variant
101*8d741a5dSApple OSS Distributions                })
102*8d741a5dSApple OSS Distributions            end
103*8d741a5dSApple OSS Distributions        end
104*8d741a5dSApple OSS Distributions    end
105*8d741a5dSApple OSS Distributionsend
106*8d741a5dSApple OSS Distributions
107*8d741a5dSApple OSS Distributionsbenchmark:finish()
108