xref: /xnu-11215.81.4/tests/vm/perf_compressor.lua (revision d4514f0bc1d3f944c22d92e68b646ac3fb40d452)
1#!/usr/local/bin/recon
2
3local benchrun = require 'benchrun'
4local perfdata = require 'perfdata'
5local csv = require 'csv'
6local sysctl = require 'sysctl'
7
8require 'strict'
9
10local kDefaultDuration = 15
11
12local benchmark = benchrun.new {
13    name = 'xnu.perf_compressor',
14    version = 1,
15    arg = arg,
16    modify_argparser = function(parser)
17        parser:argument {
18          name = 'path',
19          description = 'Path to perf_compressor binary'
20        }
21        parser:option{
22          name = '--duration',
23          description = 'How long, in seconds, to run each iteration',
24          default = kDefaultDuration
25        }
26        parser:option{
27            name = '--variant',
28            description = 'Which benchmark variant to run',
29            default = 'compress-and-decompress',
30            choices = {'compress', 'compress-and-decompress'}
31        }
32        parser:option{
33            name = '--buffer-size',
34            description = 'MB size of buffer to send to compressor',
35            default = 100
36        }
37        parser:option{
38            name = '--data-type',
39            description = 'Fill the buffer with random, zero, or typical data',
40            default = 'typical',
41            choices = {'typical', 'random', 'zero'}
42        }
43        parser:flag {
44            name = '--verbose',
45            description = 'Print benchmark progress',
46        }
47    end
48}
49local is_development_kernel, err = sysctl("kern.development")
50benchmark:assert(err == nil, "Unable to check for development kernel")
51if is_development_kernel == 0 then
52    print "Skipping benchmark on non-development kernel."
53    os.exit(0)
54end
55local hw_page_size, err = sysctl("hw.pagesize")
56benchmark:assert(err == nil, "Unable to check hw page size")
57local vm_page_size, err = sysctl("vm.pagesize")
58benchmark:assert(err == nil, "Unable to check vm page size")
59local product_name = benchmark:spawn{'/usr/bin/sw_vers', '-productName'}
60if hw_page_size ~= vm_page_size then
61    benchmark:print "Skipping benchmark on this platform because benchmark process has a different page size than the kernel"
62    os.exit(0)
63elseif string.find(product_name, "Watch OS") or string.find(product_name, "TVOS") then
64    -- rdar://103802544: Temporarily disable test for watchOS and tvOS
65    benchmark:print "Skipping benchmark on this platform as a temporary workaround to avoid device panics"
66    os.exit(0)
67end
68
69args = {benchmark.opt.path, benchmark.opt.variant, benchmark.opt.data_type, benchmark.opt.duration, benchmark.opt.buffer_size}
70if benchmark.opt.verbose then
71    table.insert(args, 2, "-v")
72    args["echo"] = true
73end
74for out in benchmark:run(args) do
75    local result = out:match("-----Results-----\n(.*)")
76    benchmark:assert(result, "Unable to find result data in output")
77    local data = csv.openstring(result, {header = true})
78    for field in data:lines() do
79        for k, v in pairs(field) do
80            unit = perfdata.unit.bytes_per_second
81            if k == "Compression Ratio" then
82                unit = perfdata.unit.custom("uncompressed / compressed")
83            end
84            benchmark.writer:add_value(k, unit, tonumber(v), {
85                data_type = benchmark.opt.data_type,
86                buffer_size = benchmark.opt.buffer_size,
87                [perfdata.larger_better] = true
88            })
89        end
90    end
91end
92
93benchmark:finish()
94