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