1#!/usr/bin/perl
2
3# Check the functionality of the Porting/bench.pl executable;
4# in particular, its argument handling and its ability to produce
5# the expected output for particular arguments.
6#
7# See also t/porting/bench_selftest.pl
8
9BEGIN {
10    chdir '..' if -f 'test.pl';
11    @INC = ( './lib' );
12    require './t/test.pl';
13}
14
15use warnings;
16use strict;
17use Config;
18
19
20# Only test on git checkouts - this is more of a perl core developer
21# tool than an end-user tool.
22# Only test on a platform likely to support forking, pipes, cachegrind
23# etc.  Add other platforms if you think they're safe.
24
25skip_all "not devel"   unless -d "./.git";
26skip_all "not linux"   unless $^O eq 'linux';
27skip_all "no valgrind" unless -x '/bin/valgrind' || -x '/usr/bin/valgrind';
28# Address sanitizer clashes horribly with cachegrind
29skip_all "not with ASAN" if $Config{ccflags} =~ /sanitize=address/;
30# If this takes more than 15 second then something is very wrong
31skip_all "cachegrind broken" if system "( ulimit -c 0; ulimit -t 15; valgrind -q --tool=cachegrind --cachegrind-out-file=/dev/null $^X -e0 ) 2>/dev/null";
32
33
34my $bench_pl = "Porting/bench.pl";
35
36ok -e $bench_pl, "$bench_pl exists and is executable";
37
38my $bench_cmd = "$^X -Ilib $bench_pl";
39
40my ($out, $cmd);
41
42# Read in the expected output format templates and create qr//s from them.
43
44my %formats;
45my %format_qrs;
46
47{
48    my $cur;
49    while (<DATA>) {
50        next if /^#/;
51        if (/^FORMAT:/) {
52            die "invalid format line: $_" unless /^FORMAT:\s+(\w+)\s*$/;
53            $cur = $1;
54            die "duplicate format: '$cur'\n" if exists $formats{$cur};
55            next;
56        }
57        $formats{$cur} .= $_;
58    }
59
60    for my $name (sort keys %formats) {
61        my $f = $formats{$name};
62
63        # expand "%%SUB_FORMAT%%
64        $f =~ s{^ \s* %% (\w+) %% [ \t]* \n}
65               {
66                    my $f1 = $formats{$1};
67                    die "No such sub-format '%%$1%%' in format '$name'\n"
68                        unless defined $f1;
69                    $f1;
70               }gmxe;
71
72        $f = quotemeta $f;
73
74        # convert NNNN.NN placeholders into a regex
75        $f =~ s{(N+)\\.(N+)}
76               {
77                    my $l = length($2);
78                    "("
79                    . "\\s*-?\\d+\\."
80                    . "\\d" x $l
81                    ."|\\s*-)"
82               }ge;
83
84        # convert run of space chars into ' +' or ' *'
85
86        $f =~ s/(\A|\n)(\\ )+/$1 */g;
87        $f =~ s/(\\ )+/ +/g;
88
89        # convert '---' placeholders into a regex
90        $f =~ s/(\\-){2,}/-+/g;
91
92        $format_qrs{$name} = qr/\A$f\z/;
93    }
94}
95
96
97# ---------------------------------------------------
98# check croaks
99
100for my $test (
101    [
102        "--boz",
103        "Unknown option: boz\nUse the -h option for usage information.\n",
104        "croak: basic unknown option"
105    ],
106    [
107        "--fields=Ir,Boz",
108        "Error: --fields: unknown field 'Boz'\n",
109        "croak: unknown --field"
110    ],
111    [
112        "--action=boz",
113        "Error: unrecognised action 'boz'\nmust be one of: grind, selftest\n",
114        "croak: unknown --action"
115    ],
116    [
117        "--sort=boz",
118        "Error: --sort argument should be of the form field:perl: 'boz'\n",
119        "croak: invalid --sort"
120    ],
121    [
122        "--sort=boz:perl",
123        "Error: --sort: unknown field 'boz'\n",
124        "croak: unknown --sort field"
125    ],
126    [
127        "-action=selftest perl",
128        "Error: no perl executables may be specified with selftest\n",
129        "croak: --action-selftest with executable"
130    ],
131    [
132        "--tests=/boz perl",
133        "Error: --tests regex must be of the form /.../\n",
134        "croak: invalid --tests regex"
135    ],
136    [
137        "--tests=call::sub::empty,foo::bar::baz::boz perl",
138          "Error: no such test found: 'foo::bar::baz::boz'\n"
139        . "Re-run with --verbose for a list of valid tests.\n",
140        "croak: unknown test in --tests"
141    ],
142    [
143        "--verbose --tests=call::sub::empty,foo::bar::baz::boz --read=t/porting/bench/callsub.json",
144            "Error: no such test found: 'foo::bar::baz::boz'\n"
145          . "Valid test names are:\n"
146          . "  call::sub::amp_empty\n"
147          . "  call::sub::empty\n",
148        "croak: unknown test in --tests --verbose"
149    ],
150    [
151        "--tests=/foo::bar::baz::boz/ perl",
152        "Error: no tests to run\n",
153        "croak: no --tests to run "
154    ],
155    [
156        "--benchfile=no-such-file-boz perl",
157        qr/\AError: can't read 'no-such-file-boz':/,
158        "croak: non-existent --benchfile "
159    ],
160    [
161        "--benchfile=t/porting/bench/synerr perl",
162        qr{\AError: can't parse 't/porting/bench/synerr':\nsyntax error},
163        "croak: --benchfile with syntax error"
164    ],
165    [
166        "--benchfile=t/porting/bench/ret0 perl",
167        "Error: can't load 't/porting/bench/ret0': code didn't return a true value\n",
168        "croak: --benchfile which returns 0"
169    ],
170    [
171        "--benchfile=t/porting/bench/oddentry perl",
172        qr{\AError: 't/porting/bench/oddentry' does not contain evenly paired test names and hashes\n},
173        "croak: --benchfile with odd number of entries"
174    ],
175    [
176        "--benchfile=t/porting/bench/badname perl",
177        qr{\AError: 't/porting/bench/badname': invalid test name: '1='\n},
178        "croak: --benchfile with invalid test name"
179    ],
180    [
181        "--benchfile=t/porting/bench/badhash perl",
182        qr{\AError: 't/porting/bench/badhash': invalid key 'blah' for test 'foo::bar'\n},
183        "croak: --benchfile with invalid test hash key"
184    ],
185    [
186        "--norm=2 ./miniperl ./perl",
187        "Error: --norm value 2 outside range 0..1\n",
188        "croak: select-a-perl out of range"
189    ],
190    [
191        "--norm=-0 ./miniperl ./perl",
192        "Error: --norm value -0 outside range -1..-2\n",
193        "croak: select-a-perl out of range"
194    ],
195    [
196        "--norm=-3 ./miniperl ./perl",
197        "Error: --norm value -3 outside range -1..-2\n",
198        "croak: select-a-perl out of range"
199    ],
200    [
201        "--sort=Ir:myperl ./miniperl ./perl",
202        "Error: --sort: unrecognised perl 'myperl'\n"
203        . "Valid perl names are:\n"
204        . "    ./miniperl\n"
205        . "    ./perl\n",
206        "croak: select-a-perl unrecognised"
207    ],
208    [
209        "--compact=./perl ./perl=A ./perl=B",
210        "Error: --compact: ambiguous perl './perl'\n",
211        "croak: select-a-perl ambiguous"
212    ],
213    [
214        "./perl --foo",
215        "Error: unrecognised executable switch '--foo'\n",
216        "croak: ./perl --foo"
217    ],
218    [
219        "-- --args=foo",
220        "Error: --args without a preceding executable name\n",
221        "croak: --args without perl"
222    ],
223    [
224        "-- --env=foo=bar",
225        "Error: --env without a preceding executable name\n",
226        "croak: --env without perl"
227    ],
228    [
229        "./perl --args",
230        "Error: --args is missing value\n",
231        "croak: --args without value"
232    ],
233    [
234        "./perl --env",
235        "Error: --env is missing value\n",
236        "croak: --env without value"
237    ],
238    [
239        "./perl --env='FOO'",
240        "Error: --env is missing =value\n",
241        "croak: --env without =value"
242    ],
243    [
244        "./perl ./perl",
245        "Error: duplicate label './perl': each executable must have a unique label\n",
246        "croak: duplicate label ./perl ./perl"
247    ],
248    [
249        "./perl=A ./miniperl=A",
250        "Error: duplicate label 'A': each executable must have a unique label\n",
251        "croak: duplicate label =A =A"
252    ],
253    [
254        "--read=t/porting/bench/callsub.json --read=t/porting/bench/callsub.json",
255        "Error: duplicate label './perl': seen in file 't/porting/bench/callsub.json'\n",
256        "croak: duplicate label --read=... --read=..."
257    ],
258    [
259        "--read=t/porting/bench/callsub.json ./perl",
260        "Error: duplicate label './perl': seen both in --read file and on command line\n",
261        "croak: duplicate label --read=... ./perl"
262    ],
263    [
264        "./nosuch-perl",
265        qr{^\QError: unable to execute './nosuch-perl': },
266        "croak:  no such perl"
267    ],
268    [
269        "--grindargs=Boz --debug --tests=call::sub::empty ./perl=A ./perl=B",
270        qr{Error: .*?(unexpected code or cachegrind output|gave return status)}s,
271        "croak: cachegrind output format "
272    ],
273    [
274        "--bisect=Ir",,
275        "Error: --bisect option must be of form 'field,integer,integer'\n",
276        "croak: --bisect=Ir"
277    ],
278    [
279        "--bisect=Ir,1",,
280        "Error: --bisect option must be of form 'field,integer,integer'\n",
281        "croak: --bisect=Ir,1"
282    ],
283    [
284        "--bisect=Ir,1,2,3",
285        "Error: --bisect option must be of form 'field,integer,integer'\n",
286        "croak: --bisect=Ir,1,2,3"
287    ],
288    [
289        "--bisect=Ir,1,x",
290        "Error: --bisect option must be of form 'field,integer,integer'\n",
291        "croak: --bisect=Ir,1,x"
292    ],
293    [
294        "--bisect=Ir,x,2",
295        "Error: --bisect option must be of form 'field,integer,integer'\n",
296        "croak: --bisect=Ir,x,2"
297    ],
298    [
299        "--bisect=boz,1,2",
300        "Error: unrecognised field 'boz' in --bisect option\n",
301        "croak: --bisect=boz,1,2"
302    ],
303    [
304        "--bisect=Ir,2,1",
305        "Error: --bisect min (2) must be <= max (1)\n",
306        "croak: --bisect=boz,2,1"
307    ],
308    [
309        "--read=no-such-file-boz",
310        qr/\AError: can't open 'no-such-file-boz' for reading:/,
311        "croak: non-existent --read file "
312    ],
313    [
314        "--read=t/porting/bench/badversion.json",
315        "Error: unsupported version 9999.9 in file 't/porting/bench/badversion.json' (too new)\n",
316        "croak: --read version"
317    ],
318    [
319        "--read=t/porting/bench/callsub.json --benchfile=t/perf/benchmarks ./perl ",
320        "Error: --benchfile cannot be used when --read is present\n",
321        "croak: benchfile with read"
322    ],
323    [
324        "",
325        "Error: nothing to do: no perls to run, no data to read.\n",
326        "croak: no input"
327    ],
328    [
329        "./perl",
330        "Error: need at least 2 perls for comparison.\n",
331        "croak: need 2 perls"
332    ],
333    [
334        "--bisect=Ir,1,2 ./perl=A ./perl=B",
335        "Error: exactly one perl executable must be specified for bisect\n",
336        "croak: --bisect, need 1 perls"
337    ],
338    [
339        "--bisect=Ir,1,2 --tests=/call/ ./perl=A",
340        "Error: only a single test may be specified with --bisect\n",
341        "croak: --bisect one test only"
342    ],
343    # note that callsub.json was created using
344    # ./perl -Ilib Porting/bench.pl --tests='/call::sub::(amp_)?empty/' \
345    #                     --write=t/porting/bench/callsub.json ./perl
346    [
347        "--read=t/porting/bench/callsub.json --write=no/such/file/boz",
348        qr{\AError: can't open 'no/such/file/boz' for writing: },
349        "croak: --write open error"
350    ],
351    # note that callsub2.json was created using
352    # ./perl -Ilib Porting/bench.pl \
353    #    --tests='call::sub::empty,call::sub::args3' \
354    #                     --write=t/porting/bench/callsub2.json ./perl=perl2
355    [
356           "--read=t/porting/bench/callsub.json "
357        . " --read=t/porting/bench/callsub2.json",
358        "Can't merge multiple read files: they contain differing test sets.\n"
359        . "Re-run with --verbose to see the differences.\n",
360        "croak: --read callsub, callsub2"
361    ],
362    [
363           "--read=t/porting/bench/callsub.json "
364        . " --read=t/porting/bench/callsub2.json"
365        . " --verbose",
366        "Can't merge multiple read files: they contain differing test sets.\n"
367        . "Previous tests:\n"
368        . "  call::sub::amp_empty\n"
369        . "  call::sub::empty\n"
370        . "tests from 't/porting/bench/callsub2.json':\n"
371        . "  call::sub::args3\n"
372        . "  call::sub::empty\n",
373        "croak: --read callsub, callsub2 --verbose"
374    ],
375
376    # these ones aren't tested (and nor are any "Panic:" ones):
377
378    # Error: can't parse '$field' field from cachegrind output
379    # Error: while starting cachegrind subprocess for NNNN:
380    # File '$file' contains no results
381    # File '$file' contains differing test and results names
382    # File '$file' contains differing test and sort order names
383    # Can't merge multiple read files: differing loop counts:
384)
385{
386    my ($args, $expected, $desc) = @$test;
387    $out = qx($bench_cmd $args 2>&1);
388    if (ref($expected)) {
389        like $out, $expected, $desc;
390    }
391    else {
392        is $out, $expected, $desc;
393    }
394}
395
396# ---------------------------------------------------
397# run benchmarks
398
399
400my $resultfile1 = tempfile(); # benchmark results for 1 perl
401my $resultfile2 = tempfile(); # benchmark results for 2 perls
402
403# Run a real cachegrind session and write results to file.
404# the -j 2 is to minimally exercise its parallel facility.
405
406note("running cachegrind for 1st perl; may be slow...");
407$out = qx($bench_cmd -j 2 --write=$resultfile1 --tests=call::sub::empty $^X=p0 2>&1);
408is $out, "", "--write should produce no output (1 perl)";
409ok -s $resultfile1, "--write should create a non-empty results file (1 perl)";
410
411# and again with 2 perls. This is also tests the 'mix read and new
412# perls' functionality.
413
414note("running cachegrind for 2nd perl; may be slow...");
415$out = qx($bench_cmd -j 2 --read=$resultfile1 --write=$resultfile2 $^X=p1 2>&1);
416is $out, "", "--write should produce no output (2 perls)"
417    or diag("got: $out");
418ok -s $resultfile2, "--write should create a non-empty results file (2 perls)";
419
420# 1 perl:
421
422# read back the results in raw form
423
424$out = qx($bench_cmd --read=$resultfile1 --raw 2>&1);
425like $out, $format_qrs{raw1}, "basic cachegrind raw format; 1 perl";
426
427# and read back the results in raw compact form
428
429$out = qx($bench_cmd --read=$resultfile1 --raw --compact=0 2>&1);
430like $out, $format_qrs{raw_compact}, "basic cachegrind raw compact format; 1 perl";
431
432# and read back the results in raw average form
433
434$out = qx($bench_cmd --read=$resultfile1 --raw --average 2>&1);
435like $out, $format_qrs{raw_average1}, "basic cachegrind raw average format; 1 perl";
436
437# and read back the results with raw selected fields
438
439$out = qx($bench_cmd --read=$resultfile1 --raw --fields=Ir,Dr 2>&1);
440like $out, $format_qrs{fields1}, "basic cachegrind --fields; 1 perl";
441
442# 2 perls:
443
444# read back the results in relative-percent form
445
446$out = qx($bench_cmd --read=$resultfile2 2>&1);
447like $out, $format_qrs{percent2}, "basic cachegrind percent format; 2 perls";
448
449# read back the results in relative-percent form with norm
450
451$out = qx($bench_cmd --read=$resultfile2 --norm=0 2>&1);
452like $out, $format_qrs{percent2}, "basic cachegrind percent format, norm; 2 perls";
453
454# ditto with negative norm
455
456$out = qx($bench_cmd --read=$resultfile2 --norm=-2 2>&1);
457like $out, $format_qrs{percent2}, "basic cachegrind percent format, norm -2; 2 perls";
458
459# read back the results in relative-percent form with sort
460
461$out = qx($bench_cmd --read=$resultfile2 --sort=Ir:0 2>&1);
462like $out, $format_qrs{percent2}, "basic cachegrind percent format, sort; 2 perls";
463
464# read back the results in relative-percent form with sort and norm
465
466$out = qx($bench_cmd --read=$resultfile2 --sort=Ir:0 --norm=0 2>&1);
467like $out, $format_qrs{percent2}, "basic cachegrind percent format, sort, norm; 2 perls";
468
469# and read back the results in raw form
470
471$out = qx($bench_cmd --read=$resultfile2 --raw 2>&1);
472like $out, $format_qrs{raw2}, "basic cachegrind raw format; 2 perls";
473
474# and read back the results in raw form with norm
475
476$out = qx($bench_cmd --read=$resultfile2 --raw --norm=0 2>&1);
477like $out, $format_qrs{raw2}, "basic cachegrind raw format, norm; 2 perls";
478
479# and read back the results in raw form with sort
480
481$out = qx($bench_cmd --read=$resultfile2 --raw --sort=Ir:0 2>&1);
482like $out, $format_qrs{raw2}, "basic cachegrind raw format, sort, norm; 2 perls";
483
484# and read back the results in raw form with sort and norm
485
486$out = qx($bench_cmd --read=$resultfile2 --raw --sort=Ir:0 --norm=0 2>&1);
487like $out, $format_qrs{raw2}, "basic cachegrind raw format, sort, norm; 2 perls";
488
489# and read back the results in compact form
490
491$out = qx($bench_cmd --read=$resultfile2 --compact=1 2>&1);
492like $out, $format_qrs{compact}, "basic cachegrind compact format; 2 perls";
493
494# and read back the results in average form
495
496$out = qx($bench_cmd --read=$resultfile2 --average 2>&1);
497like $out, $format_qrs{average}, "basic cachegrind average format; 2 perls";
498
499# and read back the results with selected fields
500
501$out = qx($bench_cmd --read=$resultfile2 --fields=Ir,Dr 2>&1);
502like $out, $format_qrs{fields2}, "basic cachegrind --fields; 2 perls";
503
504# and read back the results in compact form with selected fields
505
506$out = qx($bench_cmd --read=$resultfile2 --compact=1  --fields=Ir,Dr 2>&1);
507like $out, $format_qrs{compact_fields}, "basic cachegrind compact, fields; 2 perls";
508
509# and read back the results with 1 selected fields (this is more compact)
510
511$out = qx($bench_cmd --read=$resultfile2 --fields=Ir 2>&1);
512like $out, $format_qrs{'1field'}, "basic cachegrind 1 field; 2 perls";
513
514
515# bisect
516
517# the Ir range here is intended such that the bisect will always fail
518$out = qx($bench_cmd --read=t/porting/bench/callsub.json --tests=call::sub::empty --bisect=Ir,100000,100001 2>&1);
519
520is $?, 1 << 8, "--bisect: exit result: should not match";
521like $out, qr/^Bisect: Ir had the value -?\d+\n/,
522        "--bisect: got expected output";
523
524# multiple reads with differing test sets but common --tests subset
525
526$out = qx($bench_cmd --read=t/porting/bench/callsub.json  --read=t/porting/bench/callsub2.json --tests=call::sub::empty 2>&1);
527$out =~ s{\Q./perl  perl2}{    p0     p1};
528$out =~ s{^\./perl}{p0}m;
529like $out, $format_qrs{percent2}, "2 reads; overlapping test sets";
530
531# A read defines what benchmarks to run
532
533note("running cachegrind on 1 perl; may be slow...");
534$out = qx($bench_cmd --read=t/porting/bench/callsub.json --tests=call::sub::empty $^X=p1 2>&1);
535$out =~ s{^\./perl}{p0}m;
536$out =~ s{\Q./perl}{    p0};
537like $out, $format_qrs{percent2}, "1 read; 1 generate";
538
539# Process environment and optional args.
540# This is a minimal test that it runs - it doesn't test whether
541# the environment and args are getting applied correctly, apart from the
542# fact that the perls in question are being successfully executed.
543#
544# Also check the --autolabel feature
545
546note("running cachegrind on 2 perls; may be slow...");
547$cmd = <<EOF;
548$bench_cmd
549    --read=t/porting/bench/callsub.json
550    --read=t/porting/bench/callsub2.json
551    --tests=call::sub::empty
552    --autolabel
553    --perlargs=-Ilib
554    $^X --args='-Ifoo/bar -Mstrict' --env='FOO=foo'
555    $^X --args='-Ifoo/bar'          --env='BAR=bar' --env='BAZ=baz'
556    2>&1
557EOF
558$cmd =~ s/\n\s+/ /g;
559$out = qx($cmd);
560$out =~ s{^\./perl}{p0}m;
561$out =~ s{\Q       ./perl  perl2    p-0    p-1}
562         {           p0     p1     p2     p3};
563like $out, $format_qrs{percent4}, "4 perls with autolabel and args and env";
564
565
566done_testing();
567
568
569# Templates for expected output formats.
570#
571# Lines starting with '#' are skipped.
572#
573# Lines of the form 'FORMAT: foo' start and name a new template
574#
575# All other lines are part of the template
576#
577# Entries of the form NNNN.NN are converted into a regex of the form
578#    ( \s* -? \d+\.\d\d | - )
579# i.e. it expects number with a fixed number of digits after the point,
580# or a '-'.
581#
582# Any runs of space chars (but not tab) are converted into ' +',
583# or ' *' if at the start of a line
584#
585# Entries of the form --- are converted into [-]+
586#
587# Lines of the form %%FOO%% are substituted with format 'FOO'
588
589
590__END__
591# ===================================================================
592FORMAT: STD_HEADER
593Key:
594    Ir   Instruction read
595    Dr   Data read
596    Dw   Data write
597    COND conditional branches
598    IND  indirect branches
599    _m   branch predict miss
600    _m1  level 1 cache miss
601    _mm  last cache (e.g. L3) miss
602    -    indeterminate percentage (e.g. 1/0)
603# ===================================================================
604FORMAT: percent2
605%%STD_HEADER%%
606
607The numbers represent relative counts per loop iteration, compared to
608p0 at 100.0%.
609Higher is better: for example, using half as many instructions gives 200%,
610while using twice as many gives 50%.
611
612call::sub::empty
613function call with no args or body
614
615           p0     p1
616       ------ ------
617    Ir 100.00 NNN.NN
618    Dr 100.00 NNN.NN
619    Dw 100.00 NNN.NN
620  COND 100.00 NNN.NN
621   IND 100.00 NNN.NN
622
623COND_m 100.00 NNN.NN
624 IND_m 100.00 NNN.NN
625
626 Ir_m1 100.00 NNN.NN
627 Dr_m1 100.00 NNN.NN
628 Dw_m1 100.00 NNN.NN
629
630 Ir_mm 100.00 NNN.NN
631 Dr_mm 100.00 NNN.NN
632 Dw_mm 100.00 NNN.NN
633# ===================================================================
634FORMAT: percent4
635%%STD_HEADER%%
636
637The numbers represent relative counts per loop iteration, compared to
638p0 at 100.0%.
639Higher is better: for example, using half as many instructions gives 200%,
640while using twice as many gives 50%.
641
642call::sub::empty
643function call with no args or body
644
645           p0     p1     p2     p3
646       ------ ------ ------ ------
647    Ir 100.00 NNN.NN NNN.NN NNN.NN
648    Dr 100.00 NNN.NN NNN.NN NNN.NN
649    Dw 100.00 NNN.NN NNN.NN NNN.NN
650  COND 100.00 NNN.NN NNN.NN NNN.NN
651   IND 100.00 NNN.NN NNN.NN NNN.NN
652
653COND_m 100.00 NNN.NN NNN.NN NNN.NN
654 IND_m 100.00 NNN.NN NNN.NN NNN.NN
655
656 Ir_m1 100.00 NNN.NN NNN.NN NNN.NN
657 Dr_m1 100.00 NNN.NN NNN.NN NNN.NN
658 Dw_m1 100.00 NNN.NN NNN.NN NNN.NN
659
660 Ir_mm 100.00 NNN.NN NNN.NN NNN.NN
661 Dr_mm 100.00 NNN.NN NNN.NN NNN.NN
662 Dw_mm 100.00 NNN.NN NNN.NN NNN.NN
663# ===================================================================
664FORMAT: fields2
665%%STD_HEADER%%
666
667The numbers represent relative counts per loop iteration, compared to
668p0 at 100.0%.
669Higher is better: for example, using half as many instructions gives 200%,
670while using twice as many gives 50%.
671
672call::sub::empty
673function call with no args or body
674
675           p0     p1
676       ------ ------
677    Ir 100.00 NNN.NN
678    Dr 100.00 NNN.NN
679# ===================================================================
680FORMAT: raw1
681%%STD_HEADER%%
682
683The numbers represent raw counts per loop iteration.
684
685call::sub::empty
686function call with no args or body
687
688             p0
689       --------
690    Ir NNNNNN.N
691    Dr NNNNNN.N
692    Dw NNNNNN.N
693  COND NNNNNN.N
694   IND NNNNNN.N
695
696COND_m NNNNNN.N
697 IND_m NNNNNN.N
698
699 Ir_m1 NNNNNN.N
700 Dr_m1 NNNNNN.N
701 Dw_m1 NNNNNN.N
702
703 Ir_mm NNNNNN.N
704 Dr_mm NNNNNN.N
705 Dw_mm NNNNNN.N
706# ===================================================================
707FORMAT: raw_average1
708%%STD_HEADER%%
709
710The numbers represent raw counts per loop iteration.
711
712AVERAGE
713
714             p0
715       --------
716    Ir NNNNNN.N
717    Dr NNNNNN.N
718    Dw NNNNNN.N
719  COND NNNNNN.N
720   IND NNNNNN.N
721
722COND_m NNNNNN.N
723 IND_m NNNNNN.N
724
725 Ir_m1 NNNNNN.N
726 Dr_m1 NNNNNN.N
727 Dw_m1 NNNNNN.N
728
729 Ir_mm NNNNNN.N
730 Dr_mm NNNNNN.N
731 Dw_mm NNNNNN.N
732# ===================================================================
733FORMAT: fields1
734%%STD_HEADER%%
735
736The numbers represent raw counts per loop iteration.
737
738call::sub::empty
739function call with no args or body
740
741             p0
742       --------
743    Ir NNNNNN.N
744    Dr NNNNNN.N
745# ===================================================================
746FORMAT: raw2
747%%STD_HEADER%%
748
749The numbers represent raw counts per loop iteration.
750
751call::sub::empty
752function call with no args or body
753
754             p0       p1
755       -------- --------
756    Ir NNNNNN.N NNNNNN.N
757    Dr NNNNNN.N NNNNNN.N
758    Dw NNNNNN.N NNNNNN.N
759  COND NNNNNN.N NNNNNN.N
760   IND NNNNNN.N NNNNNN.N
761
762COND_m NNNNNN.N NNNNNN.N
763 IND_m NNNNNN.N NNNNNN.N
764
765 Ir_m1 NNNNNN.N NNNNNN.N
766 Dr_m1 NNNNNN.N NNNNNN.N
767 Dw_m1 NNNNNN.N NNNNNN.N
768
769 Ir_mm NNNNNN.N NNNNNN.N
770 Dr_mm NNNNNN.N NNNNNN.N
771 Dw_mm NNNNNN.N NNNNNN.N
772# ===================================================================
773FORMAT: compact
774%%STD_HEADER%%
775
776The numbers represent relative counts per loop iteration, compared to
777p0 at 100.0%.
778Higher is better: for example, using half as many instructions gives 200%,
779while using twice as many gives 50%.
780
781Results for p1
782
783     Ir     Dr     Dw   COND    IND COND_m  IND_m  Ir_m1  Dr_m1  Dw_m1  Ir_mm  Dr_mm  Dw_mm
784 ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
785 NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN NNN.NN  call::sub::empty   function call with no args or body
786# ===================================================================
787FORMAT: compact_fields
788%%STD_HEADER%%
789
790The numbers represent relative counts per loop iteration, compared to
791p0 at 100.0%.
792Higher is better: for example, using half as many instructions gives 200%,
793while using twice as many gives 50%.
794
795Results for p1
796
797     Ir     Dr
798 ------ ------
799 NNN.NN NNN.NN  call::sub::empty   function call with no args or body
800# ===================================================================
801FORMAT: 1field
802%%STD_HEADER%%
803
804The numbers represent relative counts per loop iteration, compared to
805p0 at 100.0%.
806Higher is better: for example, using half as many instructions gives 200%,
807while using twice as many gives 50%.
808
809Results for field Ir
810
811                     p0     p1
812                 ------ ------
813call::sub::empty NNN.NN NNN.NN
814# ===================================================================
815FORMAT: average
816%%STD_HEADER%%
817
818The numbers represent relative counts per loop iteration, compared to
819p0 at 100.0%.
820Higher is better: for example, using half as many instructions gives 200%,
821while using twice as many gives 50%.
822
823AVERAGE
824
825           p0     p1
826       ------ ------
827    Ir 100.00 NNN.NN
828    Dr 100.00 NNN.NN
829    Dw 100.00 NNN.NN
830  COND 100.00 NNN.NN
831   IND 100.00 NNN.NN
832
833COND_m 100.00 NNN.NN
834 IND_m 100.00 NNN.NN
835
836 Ir_m1 100.00 NNN.NN
837 Dr_m1 100.00 NNN.NN
838 Dw_m1 100.00 NNN.NN
839
840 Ir_mm 100.00 NNN.NN
841 Dr_mm 100.00 NNN.NN
842 Dw_mm 100.00 NNN.NN
843# ===================================================================
844FORMAT: raw_compact
845%%STD_HEADER%%
846
847The numbers represent raw counts per loop iteration.
848
849Results for p0
850
851      Ir      Dr      Dw    COND     IND  COND_m   IND_m   Ir_m1   Dr_m1   Dw_m1   Ir_mm   Dr_mm   Dw_mm
852  ------  ------  ------  ------  ------  ------  ------  ------  ------  ------  ------  ------  ------
853 NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N NNNNN.N  call::sub::empty   function call with no args or body
854# ===================================================================
855