[cage] Add some karma aliases for myself
[parrot.git] / tools / dev / bench_op.pir
blob79479aa661c3f072fd9978bb71eae1ddda601602
1 # Copyright (C) 2004-2009, Parrot Foundation.
2 # $Id$
4 =head1 TITLE
6 bench_op - Benchmark one or more opcodes
8 =head1 SYNOPSIS
10   parrot bench_op.pir 'add $I0, $I1, $I2'
11   parrot bench_op.pir --preops='newclass $P0, "Foo"' file_w_ops.pir
12   parrot bench_op.pir --help
14 =head1 DESCRIPTION
16 The given opcode(s) are compiled into a sequence:
18   .sub _entry0
19     .param int N
20     .local int i
21     #
22     # preops go here
23     #
24     null i
25   loop:
26     #
27     # ops go here
28     #
29     inc i
30     lt i, N, loop
31   .end
33 so they should conform to Parrot Calling Conventions.
34 The code gets executed with the PIR compiler - using symbolic variables is always ok.
36 Output is the time in seconds for 1.000.000 instruction(s).
38 =head1 OPTIONS
40 =over 4
42 =item I<--times=N>
44 Run the given opcode(s) in a loop I<N> time.
45 If no I<--times> options is given 100.000 is used.
47 =item I<--verbose=i>
49 Set I<--verbose> to 1 to see the total time.
50 Set I<--verbose> to 2 to see the compiled programs.
52 =item I<--preops='opcode(s)'>
54 Execute the given opcodes in front of the loop. This is needed for ops,
55 that have side effects like B<newclass>.
57 =item I<--help>
59 Print a short description and exit.
61 =item I<--version>
63 Print program version and exit.
65 =back
67 =cut
69 .const string VERSION = "0.1.1"
71 .sub main :main
72     .param pmc argv
74     load_bytecode "Getopt/Obj.pbc"
76     .local int times
77     times = 100000
79     .local int verbose
80     verbose = 0
82     # Specification of command line arguments.
83     .local pmc getopts
84     getopts = new "Getopt::Obj"
85     # getopts."notOptStop"(1)
86     push getopts, "version"
87     push getopts, "verbose=i"
88     push getopts, "help"
89     push getopts, "times=i"
90     push getopts, "preops=s"
92     .local string program
93     shift program, argv
95     .local pmc opt
96     opt = getopts."get_options"(argv)
98     .local int argc
99     argc = argv
100     unless argc goto do_help
102     .local int def
103     def = defined opt
104     unless def goto do_help
105     def = defined opt["version"]
106     if def goto do_def
107     def = defined opt["help"]
108     if def goto do_help
109     def = defined opt["times"]
110     unless def goto default_times
111     times = opt["times"]
112 default_times:
113     def = defined opt["verbose"]
114     unless def goto default_verbose
115         verbose = opt["verbose"]
116 default_verbose:
117     .local string preops
118     def = defined opt["preops"]
119     unless def goto default_preops
120         preops = opt["preops"]
121 default_preops:
122     _run( argv, times, verbose, preops)
123     end
125 do_def:
126     print program
127     print ": Version "
128     print VERSION
129     print "\n"
130     end
132 do_help:
133     print program
134     print " [--help] [--version] [--verbose=i]] [--times=N] \\ \n"
135     print "\t[--preops='op(s)'] file | opcode\n"
136     print "\nRun opcode on commandline or from file <N> times.\n"
137     print "s. perldoc -F "
138     print program
139     print "\n"
140     end
141 .end
143 .sub _run
144     .param pmc argv
145     .param int times
146     .param int verbose
147     .param string preops
149     .local string op
150     shift op, argv
151     unless verbose goto no_v1
152         print "Running '"
153         print op
154         print "' "
155         print times
156         print " times\n"
157 no_v1:
158     # op may be a file or an opcode - try to open it
159     .local pmc F
160     open F, op, 'r'
161     .local int def
162     def = defined F
163     unless def goto op_is_op
164         read op, F, 10000       # TODO use stat
165         close F
166 op_is_op:
167     .local num empty
168     empty = _bench(times, verbose, '', '')
169     unless verbose goto no_v2
170         print "Empty "
171         print empty
172         print "\n"
173 no_v2:
174     .local num test
175     .local num diff
176     test = _bench(times, verbose, op, preops)
177     diff = test - empty
178     unless verbose goto no_v3
179         print "Total "
180         print test
181         print "\n"
182         print "Prog  "
183         print diff
184         print "\n"
185 no_v3:
186     test = diff * 1.0E6
187     test = test / times
188     print "Time for 1 million instructions: "
189     print test
190     print "\n"
191 .end
193 .sub _bench
194     .param int n
195     .param int verbose
196     .param string ops
197     .param string preops
199     .local pmc compiler
200     .local pmc compiled
201     .local int l
202     .local string ls
203     .local string prog
205     length l, ops
206     ls = l
207     .local string entry_label
208     entry_label = "_entry" . ls
209     compreg compiler, "PIR"     # TODO PASM option
210     prog = ".sub " . entry_label
211     prog = prog . "\n.param int N\n.local int i\nnull i\n"
212     prog = prog . preops
213     prog = prog . "\nloop:\n"
214     prog = prog . ops
215     prog = prog . "\ninc i\nlt i, N, loop\n.end\n"
216     if verbose < 2 goto no_v2
217         print "\n#---------\n"
218         print prog
219         print "#---------\n"
220 no_v2:
221     compiled = compiler(prog)
222     .local num now
223     time now
224     .local pmc entry
225     find_global entry, entry_label
226     entry(n)
227     .local num later
228     time later
229     later = later - now
231     .return(later)
232 .end
234 =head1 BUGS
236 You can't use the variables I<i> and I<N> nor the labels I<loop:> and
237 I<_entry\d> in your opcodes.
239 =head1 AUTHOR
241 Leopold Toetsch <lt@toetsch.at>
243 =cut
245 # Local Variables:
246 #   mode: pir
247 #   fill-column: 100
248 # End:
249 # vim: expandtab shiftwidth=4 ft=pir: