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 100 RRD files (and sync them to disk)
26 2) Update the 100 RRD file three times in a row.
27 We run the Update several times to see the difference
28 it makes in the cache.
30 3) Go back to 1)
32 NOTE
34 use strict;
35 use Time::HiRes qw(time);
36 use RRDs;
37 use IO::File;
38 use Time::HiRes qw( usleep );
40 sub create($$){
41 my $file = shift;
42 my $time = shift;
43 my $start = time; #since we loaded HiRes
44 RRDs::create ( $file.".rrd", "-b$time", qw(
45 -s300
46 DS:in:GAUGE:400:U:U
47 DS:out:GAUGE:400:U:U
48 RRA:AVERAGE:0.5:1:600
49 RRA:AVERAGE:0.5:6:600
50 RRA:MAX:0.5:6:600
51 RRA:AVERAGE:0.5:24:600
52 RRA:MAX:0.5:24:600
53 RRA:AVERAGE:0.5:144:600
54 RRA:MAX:0.5:144:600
55 ));
56 my $total = time - $start;
57 my $error = RRDs::error;
58 die $error if $error;
59 return $total;
60 }
62 sub update($$){
63 my $file = shift;
64 my $time = shift;
65 my $in = rand(1000);
66 my $out = rand(1000);
67 my $start = time;
68 my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
69 # print join("",map {" $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
70 # sync updates to disk immediately
71 # usleep(1) if (rand(3) <1 );
72 my $total = time - $start;
73 my $error = RRDs::error;
74 die $error if $error;
75 return $total;
76 }
78 sub tune($){
79 my $file = shift;
80 my $start = time;
81 RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
82 my $total = time - $start;
83 my $error = RRDs::error;
84 die $error if $error;
85 return $total;
86 }
88 sub infofetch($){
89 my $file = shift;
90 my $start = time;
91 my $info = RRDs::info ($file.".rrd");
92 my $error = RRDs::error;
93 die $error if $error;
94 my $lasttime = $info->{last_update} - $info->{last_update} % $info->{step};
95 my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
96 my $total = time - $start;
97 my $error = RRDs::error;
98 die $error if $error;
99 return $total;
100 }
102 sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
103 my $sum = shift;
104 my $squaresum = shift;
105 my $count = shift;
106 return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
107 }
109 sub makerrds($$$$){
110 my $count = shift;
111 my $total = shift;
112 my $list = shift;
113 my $time = shift;
114 my @files;
115 for (1..$count){
116 my $id = sprintf ("%07d",$total);
117 $id =~ s/^(.)(.)(.)(.)(.)//;
118 push @$list, "$1/$2/$3/$4/$5/$id";
119 -d "$1" or mkdir "$1";
120 -d "$1/$2" or mkdir "$1/$2";
121 -d "$1/$2/$3" or mkdir "$1/$2/$3";
122 -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
123 -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
124 push @files, $list->[$total];
125 create $list->[$total++],$time-2;
126 print STDERR ".";
127 }
128 for (@files){
129 my $fd = new IO::File("$_.rrd","r");
130 if (defined $fd) {
131 $fd->sync;
132 $fd->close;
133 } else {
134 warn "failed to sync $_\n";
135 }
136 }
137 return $count;
138 }
141 sub main (){
142 mkdir "db-$$" or die $!;
143 chdir "db-$$";
145 my $step = 100000; # number of rrds to creat for every round
147 my @path;
148 my $time=int(time);
150 my $tracksize = 0;
151 my $uppntr = 0;
154 my %squaresum = ( cr => 0, up => 0 );
155 my %sum = ( cr => 0, up => 0 );
156 my %count =( cr => 0, up => 0 );
158 my $printtime = time;
159 while (1) {
160 # enhance the track
161 $time += 300;
162 $tracksize += makerrds $step,$tracksize,\@path,$time;
163 # run benchmark
164 for (0..10){
165 $time += 300;
166 my $count = 0;
167 my $sum = 0;
168 my $squaresum = 0;
169 for (my $i = 0; $i<$tracksize;$i ++){
170 my $elapsed = update($path[$i],$time);
171 $sum += $elapsed;
172 $squaresum += $elapsed**2;
173 $count++;
174 };
175 # for (my $i = 0; $i<$tracksize;$i ++){
176 # my $fh = new IO::File "$path[$i].rrd","r";
177 # if (defined $fh) {
178 # $fh->sync;
179 # $fh->close;
180 # } else {
181 # warn "failed to sync $path[$i]\n";
182 # }
183 # }
184 my $ups = $count/$sum;
185 my $sdv = stddev($sum,$squaresum,$count);
186 printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
187 }
188 print STDERR "\n";
189 exit ;
190 }
191 }
193 main;