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