1 #! @PERL@
2 #
3 # $Id:$
4 #
5 # Created By Tobi Oetiker <tobi@oetiker.ch>
6 # Date 2006-10-27
7 #
8 #makes programm work AFTER install
10 use lib qw( @prefix@/lib/perl );
12 print <<NOTE;
14 RRDtool Performance Tester
15 --------------------------
16 Runnion on $RRDs::VERSION;
18 RRDtool update performance is ultimately disk-bound. Since very little data
19 does actually get written to disk in a single update, the performance
20 is highly dependent on the cache situation in your machine.
22 This test tries to cater for this. It works like this:
24 1) Create 20k RRD files (and sync them to disk)
26 2) Update the RRD files several times in a row.
27 We run the Update several times to see the difference
28 it makes in the cache.
30 NOTE
32 use strict;
33 use Time::HiRes qw(time);
34 use RRDs;
35 use IO::File;
36 use Time::HiRes qw( usleep );
38 sub create($$){
39 my $file = shift;
40 my $time = shift;
41 my $start = time; #since we loaded HiRes
42 RRDs::create ( $file.".rrd", "-b$time", qw(
43 -s300
44 DS:in:GAUGE:400:U:U
45 DS:out:GAUGE:400:U:U
46 RRA:AVERAGE:0.5:1:600
47 RRA:AVERAGE:0.5:6:600
48 RRA:MAX:0.5:6:600
49 RRA:AVERAGE:0.5:24:600
50 RRA:MAX:0.5:24:600
51 RRA:AVERAGE:0.5:144:600
52 RRA:MAX:0.5:144:600
53 ));
54 my $total = time - $start;
55 my $error = RRDs::error;
56 die $error if $error;
57 return $total;
58 }
60 sub update($$){
61 my $file = shift;
62 my $time = shift;
63 my $in = rand(1000);
64 my $out = rand(1000);
65 my $start = time;
66 my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
67 # print join("",map {" $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
68 # sync updates to disk immediately
69 # usleep(1) if (rand(3) <1 );
70 my $total = time - $start;
71 my $error = RRDs::error;
72 die $error if $error;
73 return $total;
74 }
76 sub tune($){
77 my $file = shift;
78 my $start = time;
79 RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
80 my $total = time - $start;
81 my $error = RRDs::error;
82 die $error if $error;
83 return $total;
84 }
86 sub infofetch($){
87 my $file = shift;
88 my $start = time;
89 my $info = RRDs::info ($file.".rrd");
90 my $error = RRDs::error;
91 die $error if $error;
92 my $lasttime = $info->{last_update} - $info->{last_update} % $info->{step};
93 my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
94 my $total = time - $start;
95 my $error = RRDs::error;
96 die $error if $error;
97 return $total;
98 }
100 sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
101 my $sum = shift;
102 my $squaresum = shift;
103 my $count = shift;
104 return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
105 }
107 sub makerrds($$$$){
108 my $count = shift;
109 my $total = shift;
110 my $list = shift;
111 my $time = shift;
112 my @files;
113 for (1..$count){
114 my $id = sprintf ("%07d",$total);
115 $id =~ s/^(.)(.)(.)(.)(.)//;
116 push @$list, "$1/$2/$3/$4/$5/$id";
117 -d "$1" or mkdir "$1";
118 -d "$1/$2" or mkdir "$1/$2";
119 -d "$1/$2/$3" or mkdir "$1/$2/$3";
120 -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
121 -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
122 push @files, $list->[$total];
123 create $list->[$total++],$time-2;
124 print STDERR ".";
125 }
126 for (@files){
127 my $fd = new IO::File("$_.rrd","r");
128 if (defined $fd) {
129 $fd->sync;
130 $fd->close;
131 } else {
132 warn "failed to sync $_\n";
133 }
134 }
135 return $count;
136 }
139 sub main (){
140 mkdir "db-$$" or die $!;
141 chdir "db-$$";
143 my $step = 100000; # number of rrds to creat for every round
145 my @path;
146 my $time=int(time);
148 my $tracksize = 0;
149 my $uppntr = 0;
152 my %squaresum = ( cr => 0, up => 0 );
153 my %sum = ( cr => 0, up => 0 );
154 my %count =( cr => 0, up => 0 );
156 my $printtime = time;
157 while (1) {
158 # enhance the track
159 $time += 300;
160 $tracksize += makerrds $step,$tracksize,\@path,$time;
161 # run benchmark
162 for (0..10){
163 $time += 300;
164 my $count = 0;
165 my $sum = 0;
166 my $squaresum = 0;
167 for (my $i = 0; $i<$tracksize;$i ++){
168 my $elapsed = update($path[$i],$time);
169 $sum += $elapsed;
170 $squaresum += $elapsed**2;
171 $count++;
172 };
173 # for (my $i = 0; $i<$tracksize;$i ++){
174 # my $fh = new IO::File "$path[$i].rrd","r";
175 # if (defined $fh) {
176 # $fh->sync;
177 # $fh->close;
178 # } else {
179 # warn "failed to sync $path[$i]\n";
180 # }
181 # }
182 my $ups = $count/$sum;
183 my $sdv = stddev($sum,$squaresum,$count);
184 printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
185 }
186 print STDERR "\n";
187 exit ;
188 }
189 }
191 main;
192 use strict;
193 use Time::HiRes qw(time);
194 use RRDs;
195 use IO::File;
196 use Time::HiRes qw( usleep );
198 sub create($$){
199 my $file = shift;
200 my $time = shift;
201 my $start = time; #since we loaded HiRes
202 RRDs::create ( $file.".rrd", "-b$time", qw(
203 -s300
204 DS:in:GAUGE:400:U:U
205 DS:out:GAUGE:400:U:U
206 RRA:AVERAGE:0.5:1:600
207 RRA:AVERAGE:0.5:6:600
208 RRA:MAX:0.5:6:600
209 RRA:AVERAGE:0.5:24:600
210 RRA:MAX:0.5:24:600
211 RRA:AVERAGE:0.5:144:600
212 RRA:MAX:0.5:144:600
213 ));
214 my $total = time - $start;
215 my $error = RRDs::error;
216 die $error if $error;
217 return $total;
218 }
220 sub update($$){
221 my $file = shift;
222 my $time = shift;
223 my $in = rand(1000);
224 my $out = rand(1000);
225 my $start = time;
226 my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
227 # print join("",map {" $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
228 # sync updates to disk immediately
229 # usleep(1) if (rand(3) <1 );
230 my $total = time - $start;
231 my $error = RRDs::error;
232 die $error if $error;
233 return $total;
234 }
236 sub tune($){
237 my $file = shift;
238 my $start = time;
239 RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
240 my $total = time - $start;
241 my $error = RRDs::error;
242 die $error if $error;
243 return $total;
244 }
246 sub infofetch($){
247 my $file = shift;
248 my $start = time;
249 my $info = RRDs::info ($file.".rrd");
250 my $error = RRDs::error;
251 die $error if $error;
252 my $lasttime = $info->{last_update} - $info->{last_update} % $info->{step};
253 my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
254 my $total = time - $start;
255 my $error = RRDs::error;
256 die $error if $error;
257 return $total;
258 }
260 sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
261 my $sum = shift;
262 my $squaresum = shift;
263 my $count = shift;
264 return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
265 }
267 sub makerrds($$$$){
268 my $count = shift;
269 my $total = shift;
270 my $list = shift;
271 my $time = shift;
272 my @files;
273 for (1..$count){
274 my $id = sprintf ("%07d",$total);
275 $id =~ s/^(.)(.)(.)(.)(.)//;
276 push @$list, "$1/$2/$3/$4/$5/$id";
277 -d "$1" or mkdir "$1";
278 -d "$1/$2" or mkdir "$1/$2";
279 -d "$1/$2/$3" or mkdir "$1/$2/$3";
280 -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
281 -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
282 push @files, $list->[$total];
283 create $list->[$total++],$time-2;
284 print STDERR ".";
285 }
286 for (@files){
287 my $fd = new IO::File("$_.rrd","r");
288 if (defined $fd) {
289 $fd->sync;
290 $fd->close;
291 } else {
292 warn "failed to sync $_\n";
293 }
294 }
295 return $count;
296 }
299 sub main (){
300 mkdir "db-$$" or die $!;
301 chdir "db-$$";
303 my $step = 200000; # number of rrds to creat for every round
305 my @path;
306 my $time=int(time);
308 my $tracksize = 0;
309 my $uppntr = 0;
312 my %squaresum = ( cr => 0, up => 0 );
313 my %sum = ( cr => 0, up => 0 );
314 my %count =( cr => 0, up => 0 );
316 my $printtime = time;
317 while (1) {
318 # enhance the track
319 $time += 300;
320 $tracksize += makerrds $step,$tracksize,\@path,$time;
321 # run benchmark
322 for (0..10){
323 $time += 300;
324 my $count = 0;
325 my $sum = 0;
326 my $squaresum = 0;
327 for (my $i = 0; $i<$tracksize;$i ++){
328 my $elapsed = update($path[$i],$time);
329 $sum += $elapsed;
330 $squaresum += $elapsed**2;
331 $count++;
332 };
333 # for (my $i = 0; $i<$tracksize;$i ++){
334 # my $fh = new IO::File "$path[$i].rrd","r";
335 # if (defined $fh) {
336 # $fh->sync;
337 # $fh->close;
338 # } else {
339 # warn "failed to sync $path[$i]\n";
340 # }
341 # }
342 my $ups = $count/$sum;
343 my $sdv = stddev($sum,$squaresum,$count);
344 printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
345 }
346 print STDERR "\n";
347 exit ;
348 }
349 }
351 main;