This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
bench.pl: add checks for bad benchmark files
[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         "--benchfile=t/porting/bench/oddentry perl",
173         qr{\AError: 't/porting/bench/oddentry' does not contain evenly paired test names and hashes\n},
174         "croak: --benchfile with odd number of entries"
175     ],
176     [
177         "--benchfile=t/porting/bench/badname perl",
178         qr{\AError: 't/porting/bench/badname': invalid test name: '1='\n},
179         "croak: --benchfile with invalid test name"
180     ],
181     [
182         "--benchfile=t/porting/bench/badhash perl",
183         qr{\AError: 't/porting/bench/badhash': invalid key 'blah' for test 'foo::bar'\n},
184         "croak: --benchfile with invalid test hash key"
185     ],
186     [
187         "--norm=2 ./miniperl ./perl",
188         "Error: --norm value 2 outside range 0..1\n",
189         "croak: select-a-perl out of range"
190     ],
191     [
192         "--norm=-0 ./miniperl ./perl",
193         "Error: --norm value -0 outside range -1..-2\n",
194         "croak: select-a-perl out of range"
195     ],
196     [
197         "--norm=-3 ./miniperl ./perl",
198         "Error: --norm value -3 outside range -1..-2\n",
199         "croak: select-a-perl out of range"
200     ],
201     [
202         "--sort=Ir:myperl ./miniperl ./perl",
203         "Error: --sort: unrecognised perl 'myperl'\n"
204         . "Valid perl names are:\n"
205         . "    ./miniperl\n"
206         . "    ./perl\n",
207         "croak: select-a-perl unrecognised"
208     ],
209     [
210         "--compact=./perl ./perl=A ./perl=B",
211         "Error: --compact: ambiguous perl './perl'\n",
212         "croak: select-a-perl ambiguous"
213     ],
214     [
215         "./perl --foo",
216         "Error: unrecognised executable switch '--foo'\n",
217         "croak: ./perl --foo"
218     ],
219     [
220         "-- --args=foo",
221         "Error: --args without a preceding executable name\n",
222         "croak: --args without perl"
223     ],
224     [
225         "-- --env=foo=bar",
226         "Error: --env without a preceding executable name\n",
227         "croak: --env without perl"
228     ],
229     [
230         "./perl --args",
231         "Error: --args is missing value\n",
232         "croak: --args without value"
233     ],
234     [
235         "./perl --env",
236         "Error: --env is missing value\n",
237         "croak: --env without value"
238     ],
239     [
240         "./perl --env='FOO'",
241         "Error: --env is missing =value\n",
242         "croak: --env without =value"
243     ],
244     [
245         "./perl ./perl",
246         "Error: duplicate label './perl': each executable must have a unique label\n",
247         "croak: duplicate label ./perl ./perl"
248     ],
249     [
250         "./perl=A ./miniperl=A",
251         "Error: duplicate label 'A': each executable must have a unique label\n",
252         "croak: duplicate label =A =A"
253     ],
254     [
255         "--read=t/porting/bench/callsub.json --read=t/porting/bench/callsub.json",
256         "Error: duplicate label './perl': seen in file 't/porting/bench/callsub.json'\n",
257         "croak: duplicate label --read=... --read=..."
258     ],
259     [
260         "--read=t/porting/bench/callsub.json ./perl",
261         "Error: duplicate label './perl': seen both in --read file and on command line\n",
262         "croak: duplicate label --read=... ./perl"
263     ],
264     [
265         "./nosuch-perl",
266         qr{^\QError: unable to execute './nosuch-perl': },
267         "croak:  no such perl"
268     ],
269     [
270         "--grindargs=Boz --debug --tests=call::sub::empty ./perl=A ./perl=B",
271         qr{Error: .*?(unexpected code or cachegrind output|gave return status)}s,
272         "croak: cachegrind output format "
273     ],
274     [
275         "--bisect=Ir",,
276         "Error: --bisect option must be of form 'field,integer,integer'\n",
277         "croak: --bisect=Ir"
278     ],
279     [
280         "--bisect=Ir,1",,
281         "Error: --bisect option must be of form 'field,integer,integer'\n",
282         "croak: --bisect=Ir,1"
283     ],
284     [
285         "--bisect=Ir,1,2,3",
286         "Error: --bisect option must be of form 'field,integer,integer'\n",
287         "croak: --bisect=Ir,1,2,3"
288     ],
289     [
290         "--bisect=Ir,1,x",
291         "Error: --bisect option must be of form 'field,integer,integer'\n",
292         "croak: --bisect=Ir,1,x"
293     ],
294     [
295         "--bisect=Ir,x,2",
296         "Error: --bisect option must be of form 'field,integer,integer'\n",
297         "croak: --bisect=Ir,x,2"
298     ],
299     [
300         "--bisect=boz,1,2",
301         "Error: unrecognised field 'boz' in --bisect option\n",
302         "croak: --bisect=boz,1,2"
303     ],
304     [
305         "--bisect=Ir,2,1",
306         "Error: --bisect min (2) must be <= max (1)\n",
307         "croak: --bisect=boz,2,1"
308     ],
309     [
310         "--read=no-such-file-boz",
311         qr/\AError: can't open 'no-such-file-boz' for reading:/,
312         "croak: non-existent --read file "
313     ],
314     [
315         "--read=t/porting/bench/badversion.json",
316         "Error: unsupported version 9999.9 in file 't/porting/bench/badversion.json' (too new)\n",
317         "croak: --read version"
318     ],
319     [
320         "--read=t/porting/bench/callsub.json --benchfile=t/perf/benchmarks ./perl ",
321         "Error: --benchfile cannot be used when --read is present\n",
322         "croak: benchfile with read"
323     ],
324     [
325         "",
326         "Error: nothing to do: no perls to run, no data to read.\n",
327         "croak: no input"
328     ],
329     [
330         "./perl",
331         "Error: need at least 2 perls for comparison.\n",
332         "croak: need 2 perls"
333     ],
334     [
335         "--bisect=Ir,1,2 ./perl=A ./perl=B",
336         "Error: exactly one perl executable must be specified for bisect\n",
337         "croak: --bisect, need 1 perls"
338     ],
339     [
340         "--bisect=Ir,1,2 --tests=/call/ ./perl=A",
341         "Error: only a single test may be specified with --bisect\n",
342         "croak: --bisect one test only"
343     ],
344     # note that callsub.json was created using
345     # ./perl -Ilib Porting/bench.pl --tests='/call::sub::(amp_)?empty/' \
346     #                     --write=t/porting/bench/callsub.json ./perl
347     [
348         "--read=t/porting/bench/callsub.json --write=no/such/file/boz",
349         qr{\AError: can't open 'no/such/file/boz' for writing: },
350         "croak: --write open error"
351     ],
352     # note that callsub2.json was created using
353     # ./perl -Ilib Porting/bench.pl \
354     #    --tests='call::sub::empty,call::sub::args3' \
355     #                     --write=t/porting/bench/callsub2.json ./perl=perl2
356     [
357            "--read=t/porting/bench/callsub.json "
358         . " --read=t/porting/bench/callsub2.json",
359         "Can't merge multiple read files: they contain differing test sets.\n"
360         . "Re-run with --verbose to see the differences.\n",
361         "croak: --read callsub, callsub2"
362     ],
363     [
364            "--read=t/porting/bench/callsub.json "
365         . " --read=t/porting/bench/callsub2.json"
366         . " --verbose",
367         "Can't merge multiple read files: they contain differing test sets.\n"
368         . "Previous tests:\n"
369         . "  call::sub::amp_empty\n"
370         . "  call::sub::empty\n"
371         . "tests from 't/porting/bench/callsub2.json':\n"
372         . "  call::sub::args3\n"
373         . "  call::sub::empty\n",
374         "croak: --read callsub, callsub2 --verbose"
375     ],
376
377     # these ones aren't tested (and nor are any "Panic:" ones):
378
379     # Error: can't parse '$field' field from cachegrind output
380     # Error: while starting cachegrind subprocess for NNNN:
381     # File '$file' contains no results
382     # File '$file' contains differing test and results names
383     # File '$file' contains differing test and sort order names
384     # Can't merge multiple read files: differing loop counts:
385 )
386 {
387     my ($args, $expected, $desc) = @$test;
388     $out = qx($bench_cmd $args 2>&1);
389     if (ref($expected)) {
390         like $out, $expected, $desc;
391     }
392     else {
393         is $out, $expected, $desc;
394     }
395 }
396
397 # ---------------------------------------------------
398 # run benchmarks
399
400
401 my $resultfile1 = tempfile(); # benchmark results for 1 perl
402 my $resultfile2 = tempfile(); # benchmark results for 2 perls
403
404 # Run a real cachegrind session and write results to file.
405 # the -j 2 is to minimally exercise its parallel facility.
406
407 note("running cachegrind for 1st perl; may be slow...");
408 $out = qx($bench_cmd -j 2 --write=$resultfile1 --tests=call::sub::empty $^X=p0 2>&1);
409 is $out, "", "--write should produce no output (1 perl)";
410 ok -s $resultfile1, "--write should create a non-empty results file (1 perl)";
411
412 # and again with 2 perls. This is also tests the 'mix read and new new
413 # perls' functionality.
414
415 note("running cachegrind for 2nd perl; may be slow...");
416 $out = qx($bench_cmd -j 2 --read=$resultfile1 --write=$resultfile2 $^X=p1 2>&1);
417 is $out, "", "--write should produce no output (2 perls)"
418     or diag("got: $out");
419 ok -s $resultfile2, "--write should create a non-empty results file (2 perls)";
420
421 # 1 perl:
422
423 # read back the results in raw form
424
425 $out = qx($bench_cmd --read=$resultfile1 --raw 2>&1);
426 like $out, $format_qrs{raw1}, "basic cachegrind raw format; 1 perl";
427
428 # and read back the results in raw compact form
429
430 $out = qx($bench_cmd --read=$resultfile1 --raw --compact=0 2>&1);
431 like $out, $format_qrs{raw_compact}, "basic cachegrind raw compact format; 1 perl";
432
433 # and read back the results in raw average form
434
435 $out = qx($bench_cmd --read=$resultfile1 --raw --average 2>&1);
436 like $out, $format_qrs{raw_average1}, "basic cachegrind raw average format; 1 perl";
437
438 # and read back the results with raw selected fields
439
440 $out = qx($bench_cmd --read=$resultfile1 --raw --fields=Ir,Dr 2>&1);
441 like $out, $format_qrs{fields1}, "basic cachegrind --fields; 1 perl";
442
443 # 2 perls:
444
445 # read back the results in relative-percent form
446
447 $out = qx($bench_cmd --read=$resultfile2 2>&1);
448 like $out, $format_qrs{percent2}, "basic cachegrind percent format; 2 perls";
449
450 # read back the results in relative-percent form with norm
451
452 $out = qx($bench_cmd --read=$resultfile2 --norm=0 2>&1);
453 like $out, $format_qrs{percent2}, "basic cachegrind percent format, norm; 2 perls";
454
455 # ditto with negative norm
456
457 $out = qx($bench_cmd --read=$resultfile2 --norm=-2 2>&1);
458 like $out, $format_qrs{percent2}, "basic cachegrind percent format, norm -2; 2 perls";
459
460 # read back the results in relative-percent form with sort
461
462 $out = qx($bench_cmd --read=$resultfile2 --sort=Ir:0 2>&1);
463 like $out, $format_qrs{percent2}, "basic cachegrind percent format, sort; 2 perls";
464
465 # read back the results in relative-percent form with sort and norm
466
467 $out = qx($bench_cmd --read=$resultfile2 --sort=Ir:0 --norm=0 2>&1);
468 like $out, $format_qrs{percent2}, "basic cachegrind percent format, sort, norm; 2 perls";
469
470 # and read back the results in raw form
471
472 $out = qx($bench_cmd --read=$resultfile2 --raw 2>&1);
473 like $out, $format_qrs{raw2}, "basic cachegrind raw format; 2 perls";
474
475 # and read back the results in raw form with norm
476
477 $out = qx($bench_cmd --read=$resultfile2 --raw --norm=0 2>&1);
478 like $out, $format_qrs{raw2}, "basic cachegrind raw format, norm; 2 perls";
479
480 # and read back the results in raw form with sort
481
482 $out = qx($bench_cmd --read=$resultfile2 --raw --sort=Ir:0 2>&1);
483 like $out, $format_qrs{raw2}, "basic cachegrind raw format, sort, norm; 2 perls";
484
485 # and read back the results in raw form with sort and norm
486
487 $out = qx($bench_cmd --read=$resultfile2 --raw --sort=Ir:0 --norm=0 2>&1);
488 like $out, $format_qrs{raw2}, "basic cachegrind raw format, sort, norm; 2 perls";
489
490 # and read back the results in compact form
491
492 $out = qx($bench_cmd --read=$resultfile2 --compact=1 2>&1);
493 like $out, $format_qrs{compact}, "basic cachegrind compact format; 2 perls";
494
495 # and read back the results in average form
496
497 $out = qx($bench_cmd --read=$resultfile2 --average 2>&1);
498 like $out, $format_qrs{average}, "basic cachegrind average format; 2 perls";
499
500 # and read back the results with selected fields
501
502 $out = qx($bench_cmd --read=$resultfile2 --fields=Ir,Dr 2>&1);
503 like $out, $format_qrs{fields2}, "basic cachegrind --fields; 2 perls";
504
505 # and read back the results in compact form with selected fields
506
507 $out = qx($bench_cmd --read=$resultfile2 --compact=1  --fields=Ir,Dr 2>&1);
508 like $out, $format_qrs{compact_fields}, "basic cachegrind compact, fields; 2 perls";
509
510 # and read back the results with 1 selected fields (this is more compact)
511
512 $out = qx($bench_cmd --read=$resultfile2 --fields=Ir 2>&1);
513 like $out, $format_qrs{'1field'}, "basic cachegrind 1 field; 2 perls";
514
515
516 # bisect
517
518 # the Ir range here is intended such that the bisect will always fail
519 $out = qx($bench_cmd --read=t/porting/bench/callsub.json --tests=call::sub::empty --bisect=Ir,100000,100001 2>&1);
520
521 is $?, 1 << 8, "--bisect: exit result: should not match";
522 like $out, qr/^Bisect: Ir had the value -?\d+\n/,
523         "--bisect: got expected output";
524
525 # multiple reads with differing test sets but common --tests subset
526
527 $out = qx($bench_cmd --read=t/porting/bench/callsub.json  --read=t/porting/bench/callsub2.json --tests=call::sub::empty 2>&1);
528 $out =~ s{\Q./perl  perl2}{    p0     p1};
529 $out =~ s{^\./perl}{p0}m;
530 like $out, $format_qrs{percent2}, "2 reads; overlapping test sets";
531
532 # A read defines what benchmarks to run
533
534 note("running cachegrind on 1 perl; may be slow...");
535 $out = qx($bench_cmd --read=t/porting/bench/callsub.json --tests=call::sub::empty $^X=p1 2>&1);
536 $out =~ s{^\./perl}{p0}m;
537 $out =~ s{\Q./perl}{    p0};
538 like $out, $format_qrs{percent2}, "1 read; 1 generate";
539
540 # Process environment and optional args.
541 # This is a minimal test that it runs - it doesn't test whether
542 # the environment and args are getting applied correctly, apart from the
543 # fact that the perls in question are being successfully executed.
544 #
545 # Also check the --autolabel feature
546
547 note("running cachegrind on 2 perls; may be slow...");
548 $cmd = <<EOF;
549 $bench_cmd
550     --read=t/porting/bench/callsub.json
551     --read=t/porting/bench/callsub2.json
552     --tests=call::sub::empty
553     --autolabel
554     --perlargs=-Ilib
555     $^X --args='-Ifoo/bar -Mstrict' --env='FOO=foo'
556     $^X --args='-Ifoo/bar'          --env='BAR=bar' --env='BAZ=baz'
557     2>&1
558 EOF
559 $cmd =~ s/\n\s+/ /g;
560 $out = qx($cmd);
561 $out =~ s{^\./perl}{p0}m;
562 $out =~ s{\Q       ./perl  perl2    p-0    p-1}
563          {           p0     p1     p2     p3};
564 like $out, $format_qrs{percent4}, "4 perls with autolabel and args and env";
565
566
567 done_testing();
568
569
570 # Templates for expected output formats.
571 #
572 # Lines starting with '#' are skipped.
573 #
574 # Lines of the form 'FORMAT: foo' start and name a new template
575 #
576 # All other lines are part of the template
577 #
578 # Entries of the form NNNN.NN are converted into a regex of the form
579 #    ( \s* -? \d+\.\d\d | - )
580 # i.e. it expects number with a fixed number of digits after the point,
581 # or a '-'.
582 #
583 # Any runs of space chars (but not tab) are converted into ' +',
584 # or ' *' if at the start of a line
585 #
586 # Entries of the form --- are converted into [-]+
587 #
588 # Lines of the form %%FOO%% are substituted with format 'FOO'
589
590
591 __END__
592 # ===================================================================
593 FORMAT: STD_HEADER
594 Key:
595     Ir   Instruction read
596     Dr   Data read
597     Dw   Data write
598     COND conditional branches
599     IND  indirect branches
600     _m   branch predict miss
601     _m1  level 1 cache miss
602     _mm  last cache (e.g. L3) miss
603     -    indeterminate percentage (e.g. 1/0)
604 # ===================================================================
605 FORMAT: percent2
606 %%STD_HEADER%%
607
608 The numbers represent relative counts per loop iteration, compared to
609 p0 at 100.0%.
610 Higher is better: for example, using half as many instructions gives 200%,
611 while using twice as many gives 50%.
612
613 call::sub::empty
614 function call with no args or body
615
616            p0     p1
617        ------ ------
618     Ir 100.00 NNN.NN
619     Dr 100.00 NNN.NN
620     Dw 100.00 NNN.NN
621   COND 100.00 NNN.NN
622    IND 100.00 NNN.NN
623
624 COND_m 100.00 NNN.NN
625  IND_m 100.00 NNN.NN
626
627  Ir_m1 100.00 NNN.NN
628  Dr_m1 100.00 NNN.NN
629  Dw_m1 100.00 NNN.NN
630
631  Ir_mm 100.00 NNN.NN
632  Dr_mm 100.00 NNN.NN
633  Dw_mm 100.00 NNN.NN
634 # ===================================================================
635 FORMAT: percent4
636 %%STD_HEADER%%
637
638 The numbers represent relative counts per loop iteration, compared to
639 p0 at 100.0%.
640 Higher is better: for example, using half as many instructions gives 200%,
641 while using twice as many gives 50%.
642
643 call::sub::empty
644 function call with no args or body
645
646            p0     p1     p2     p3
647        ------ ------ ------ ------
648     Ir 100.00 NNN.NN NNN.NN NNN.NN
649     Dr 100.00 NNN.NN NNN.NN NNN.NN
650     Dw 100.00 NNN.NN NNN.NN NNN.NN
651   COND 100.00 NNN.NN NNN.NN NNN.NN
652    IND 100.00 NNN.NN NNN.NN NNN.NN
653
654 COND_m 100.00 NNN.NN NNN.NN NNN.NN
655  IND_m 100.00 NNN.NN NNN.NN NNN.NN
656
657  Ir_m1 100.00 NNN.NN NNN.NN NNN.NN
658  Dr_m1 100.00 NNN.NN NNN.NN NNN.NN
659  Dw_m1 100.00 NNN.NN NNN.NN NNN.NN
660
661  Ir_mm 100.00 NNN.NN NNN.NN NNN.NN
662  Dr_mm 100.00 NNN.NN NNN.NN NNN.NN
663  Dw_mm 100.00 NNN.NN NNN.NN NNN.NN
664 # ===================================================================
665 FORMAT: fields2
666 %%STD_HEADER%%
667
668 The numbers represent relative counts per loop iteration, compared to
669 p0 at 100.0%.
670 Higher is better: for example, using half as many instructions gives 200%,
671 while using twice as many gives 50%.
672
673 call::sub::empty
674 function call with no args or body
675
676            p0     p1
677        ------ ------
678     Ir 100.00 NNN.NN
679     Dr 100.00 NNN.NN
680 # ===================================================================
681 FORMAT: raw1
682 %%STD_HEADER%%
683
684 The numbers represent raw counts per loop iteration.
685
686 call::sub::empty
687 function call with no args or body
688
689              p0
690        --------
691     Ir NNNNNN.N
692     Dr NNNNNN.N
693     Dw NNNNNN.N
694   COND NNNNNN.N
695    IND NNNNNN.N
696
697 COND_m NNNNNN.N
698  IND_m NNNNNN.N
699
700  Ir_m1 NNNNNN.N
701  Dr_m1 NNNNNN.N
702  Dw_m1 NNNNNN.N
703
704  Ir_mm NNNNNN.N
705  Dr_mm NNNNNN.N
706  Dw_mm NNNNNN.N
707 # ===================================================================
708 FORMAT: raw_average1
709 %%STD_HEADER%%
710
711 The numbers represent raw counts per loop iteration.
712
713 AVERAGE
714
715              p0
716        --------
717     Ir NNNNNN.N
718     Dr NNNNNN.N
719     Dw NNNNNN.N
720   COND NNNNNN.N
721    IND NNNNNN.N
722
723 COND_m NNNNNN.N
724  IND_m NNNNNN.N
725
726  Ir_m1 NNNNNN.N
727  Dr_m1 NNNNNN.N
728  Dw_m1 NNNNNN.N
729
730  Ir_mm NNNNNN.N
731  Dr_mm NNNNNN.N
732  Dw_mm NNNNNN.N
733 # ===================================================================
734 FORMAT: fields1
735 %%STD_HEADER%%
736
737 The numbers represent raw counts per loop iteration.
738
739 call::sub::empty
740 function call with no args or body
741
742              p0
743        --------
744     Ir NNNNNN.N
745     Dr NNNNNN.N
746 # ===================================================================
747 FORMAT: raw2
748 %%STD_HEADER%%
749
750 The numbers represent raw counts per loop iteration.
751
752 call::sub::empty
753 function call with no args or body
754
755              p0       p1
756        -------- --------
757     Ir NNNNNN.N NNNNNN.N
758     Dr NNNNNN.N NNNNNN.N
759     Dw NNNNNN.N NNNNNN.N
760   COND NNNNNN.N NNNNNN.N
761    IND NNNNNN.N NNNNNN.N
762
763 COND_m NNNNNN.N NNNNNN.N
764  IND_m NNNNNN.N NNNNNN.N
765
766  Ir_m1 NNNNNN.N NNNNNN.N
767  Dr_m1 NNNNNN.N NNNNNN.N
768  Dw_m1 NNNNNN.N NNNNNN.N
769
770  Ir_mm NNNNNN.N NNNNNN.N
771  Dr_mm NNNNNN.N NNNNNN.N
772  Dw_mm NNNNNN.N NNNNNN.N
773 # ===================================================================
774 FORMAT: compact
775 %%STD_HEADER%%
776
777 The numbers represent relative counts per loop iteration, compared to
778 p0 at 100.0%.
779 Higher is better: for example, using half as many instructions gives 200%,
780 while using twice as many gives 50%.
781
782 Results for p1
783
784      Ir     Dr     Dw   COND    IND COND_m  IND_m  Ir_m1  Dr_m1  Dw_m1  Ir_mm  Dr_mm  Dw_mm
785  ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
786  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
787 # ===================================================================
788 FORMAT: compact_fields
789 %%STD_HEADER%%
790
791 The numbers represent relative counts per loop iteration, compared to
792 p0 at 100.0%.
793 Higher is better: for example, using half as many instructions gives 200%,
794 while using twice as many gives 50%.
795
796 Results for p1
797
798      Ir     Dr
799  ------ ------
800  NNN.NN NNN.NN  call::sub::empty   function call with no args or body
801 # ===================================================================
802 FORMAT: 1field
803 %%STD_HEADER%%
804
805 The numbers represent relative counts per loop iteration, compared to
806 p0 at 100.0%.
807 Higher is better: for example, using half as many instructions gives 200%,
808 while using twice as many gives 50%.
809
810 Results for field Ir
811
812                      p0     p1
813                  ------ ------
814 call::sub::empty NNN.NN NNN.NN
815 # ===================================================================
816 FORMAT: average
817 %%STD_HEADER%%
818
819 The numbers represent relative counts per loop iteration, compared to
820 p0 at 100.0%.
821 Higher is better: for example, using half as many instructions gives 200%,
822 while using twice as many gives 50%.
823
824 AVERAGE
825
826            p0     p1
827        ------ ------
828     Ir 100.00 NNN.NN
829     Dr 100.00 NNN.NN
830     Dw 100.00 NNN.NN
831   COND 100.00 NNN.NN
832    IND 100.00 NNN.NN
833
834 COND_m 100.00 NNN.NN
835  IND_m 100.00 NNN.NN
836
837  Ir_m1 100.00 NNN.NN
838  Dr_m1 100.00 NNN.NN
839  Dw_m1 100.00 NNN.NN
840
841  Ir_mm 100.00 NNN.NN
842  Dr_mm 100.00 NNN.NN
843  Dw_mm 100.00 NNN.NN
844 # ===================================================================
845 FORMAT: raw_compact
846 %%STD_HEADER%%
847
848 The numbers represent raw counts per loop iteration.
849
850 Results for p0
851
852       Ir      Dr      Dw    COND     IND  COND_m   IND_m   Ir_m1   Dr_m1   Dw_m1   Ir_mm   Dr_mm   Dw_mm
853   ------  ------  ------  ------  ------  ------  ------  ------  ------  ------  ------  ------  ------
854  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
855 # ===================================================================