1 #!/usr/bin/perl 2 # 3 # CDDL HEADER START 4 # 5 # The contents of this file are subject to the terms of the 6 # Common Development and Distribution License (the "License"). 7 # You may not use this file except in compliance with the License. 8 # 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 # or http://www.opensolaris.org/os/licensing. 11 # See the License for the specific language governing permissions 12 # and limitations under the License. 13 # 14 # When distributing Covered Code, include this CDDL HEADER in each 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 # If applicable, add the following below this CDDL HEADER, with the 17 # fields enclosed by brackets "[]" replaced with your own identifying 18 # information: Portions Copyright [yyyy] [name of copyright owner] 19 # 20 # CDDL HEADER END 21 # 22 # 23 # Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 # Use is subject to license terms. 25 # 26 # ident "%Z%%M% %I% %E% SMI" 27 # 28 29 # 30 # Compare filebench results 31 # 32 # Usage: filebench_summary <dir1> <dir2> ... 33 # 34 35 use CGI ':standard'; 36 37 $maxiopsoverall = 0; 38 $maxiopsrate = 0; 39 $maxbandwidth = 0; 40 41 # 42 # Create html and text 43 # 44 open (HTML, ">index.html"); 45 print HTML start_html(-title=>'Filebench'); 46 print HTML "<body>"; 47 # 48 # Print aggregate flowop stats 49 # 50 foreach $dir (@ARGV) { 51 52 printf ("Generating html for $dir\n"); 53 open (PROFILE, "<$dir/thisrun.prof"); 54 $description = <PROFILE>; 55 $description =~ s/.*"(.+)".*/$1/; 56 57 $files = `ls $dir/stats.*.out $dir/*/stats.*.out 2>/dev/null`; 58 foreach $file (split(/\n/, $files)) { 59 print "file = $file\n"; 60 61 # Search backwards in-case the hostname is of FQDN or there's a 62 # '.' in $dir. 63 $rstr = reverse $file; 64 ($rfstype, $rworkload, $rprefix) = split(/\./, $rstr); 65 $prefix = reverse $rprefix; 66 $workload = reverse $rworkload; 67 $fstype = reverse $rfstype; 68 69 $dataset = $dir; 70 $dataset =~ s/.*\/(.+)$/$1/; 71 $dataset =~ s/\/$//; 72 $desc{$dataset} = "$description"; 73 74 open (STATS, $file); 75 $tmp = <STATS>; 76 while (<STATS>) { 77 ($flowop, $ops, $bandwidth, $latency, $cpu, $wait, $seconds) = split(/[ \t]+/, $_); 78 79 if (/^$/) { 80 $tmp = <STATS>; 81 ($fluff, $opcnt, $ops, $reads, $writes, $bandwidth, 82 $cpu) = split(/[ \tA-z:\/,]+/, $tmp); 83 $ops{$workload, $dataset} = $ops; 84 last; 85 } 86 87 $ops =~ s/ops\/s//; 88 $bandwidth =~ s/mb\/s//; 89 $latency =~ s/ms\/op//; 90 $cpu =~ s/us\/op//; 91 92 # Collapse shadow reads into single metric 93 if ($flowop =~ /shadowread/) { 94 $flowop = "shadow-read"; 95 } 96 97 # Collapse database writes into single metric 98 if ($flowop =~ /db.*write/) { 99 $flowop = "db-write"; 100 } 101 102 # Collapse database writes into single metric 103 if ($flowop =~ /db.*write/) { 104 $flowop = "db-write"; 105 } 106 107 $datasets{$dataset} = $dataset; 108 $workloads{$workload} = $workload; 109 110 $flowops{$flowop} = $flowop; 111 $wkl_flowops{$flowop, $workload} = $flowop; 112 $wkl_workload{$flowop, $workload} = $workload; 113 $flow_ops{$flowop, $workload, $dataset} += $ops; 114 $flow_bandwidth{$flowop, $workload, $dataset} += $bandwidth; 115 $flow_latency{$flowop, $workload, $dataset} += $latency; 116 $flow_cpu{$flowop, $workload, $dataset} += $cpu; 117 118 $bandwidth{$workload, $dataset} += $bandwidth; 119 $latency{$workload, $dataset} += $latency; 120 $cpu{$workload, $dataset} += $cpu; 121 122 $flowopcnt{$flowop, $workload, $dataset}++; 123 $workloadcnt{$workload, $dataset}++; 124 } 125 close(STATS); 126 } 127 } 128 129 # HTML IOPS 130 print HTML h1('Throughput breakdown (ops per second)'); 131 print HTML "<table border=1>"; 132 print HTML "<b><td>Workload</td>"; 133 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 134 print HTML "<td>$desc{$dataset}</td>"; 135 } 136 print HTML "</b></tr>"; 137 138 foreach $workload (sort (keys %workloads)) { 139 print HTML "<b><tr><td>$workload</td>"; 140 $last = 0; 141 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 142 $color = "white"; 143 $this = $ops{$workload, $dataset}; 144 if ($last && ($this - $last) < ($last * -0.1)) { 145 $color = "red"; 146 } 147 if ($last && ($this - $last) > ($last * 0.1)) { 148 $color = "green"; 149 } 150 printf HTML ("<td>%d</td\n", $this); 151 $last = $ops{$workload, $dataset}; 152 } 153 print HTML "</b></tr>"; 154 } 155 print HTML "</table>"; 156 157 # HTML Bandwidth 158 print HTML h1('Bandwidth breakdown (MB/s)'); 159 print HTML "<table border=1>"; 160 print HTML "<td>Workload</td>"; 161 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 162 print HTML "<td>$desc{$dataset}</td>"; 163 } 164 print HTML "</tr>"; 165 foreach $workload (sort (keys %workloads)) { 166 $bandwidth = 0; 167 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 168 $bandwidth += $bandwidth{$workload, $dataset}; 169 } 170 next if ($bandwidth == 0); 171 print HTML "<tr><td>$workload</td>"; 172 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 173 printf HTML ("<td>%d</td>\n", $bandwidth{$workload, $dataset}); 174 } 175 print HTML "</tr>"; 176 } 177 print HTML "</table>"; 178 179 # HTML Latency 180 print HTML h1('Latency breakdown (ms per op)'); 181 print HTML "<table border=1>"; 182 print HTML "<td>Workload</td>"; 183 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 184 print HTML "<td>$desc{$dataset}</td>"; 185 } 186 187 print HTML "</tr>"; 188 foreach $workload (sort (keys %workloads)) { 189 print HTML "<tr><td>$workload</td>"; 190 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 191 if ( $workloadcnt{$workload, $dataset}) { 192 printf HTML ("<td>%.1f</td>", $latency{$workload, 193 $dataset} / $workloadcnt{$workload, $dataset}); 194 } else { 195 printf HTML ("<td></td>"); 196 } 197 } 198 print HTML "</tr>"; 199 foreach $flowop (keys %wkl_flowops) { 200 next if ("$wkl_workload{$flowop}" ne "$workload"); 201 print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>"; 202 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 203 if ( $flowopcnt{$flowop, $dataset}) { 204 printf HTML ("<td>%.1f</td>\n", $flow_latency{$flowop, 205 $dataset} / $flowopcnt{$flowop, $dataset}); 206 } else { 207 printf HTML ("<td></td>"); 208 } 209 } 210 print HTML "</i></tr>"; 211 } 212 } 213 print HTML "</table>"; 214 215 # HTML Efficiency 216 print HTML h1('Efficiency breakdown (Code path length in uS/op)'); 217 print HTML "<table border=1>"; 218 print HTML "<td>Workload</td>"; 219 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 220 print HTML "<td>$desc{$dataset}</td>"; 221 } 222 print HTML "</tr>"; 223 foreach $workload (sort (keys %workloads)) { 224 print HTML "<tr><td>$workload</td>"; 225 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 226 if ($workloadcnt{$workload, $dataset}) { 227 printf HTML ("<td>%d</td>", $cpu{$workload, $dataset} 228 / $workloadcnt{$workload, $dataset}); 229 } else { 230 printf HTML ("<td></td>"); 231 } 232 } 233 print HTML "</tr>"; 234 foreach $flowop (keys %wkl_flowops) { 235 next if ("$wkl_workload{$flowop}" ne "$workload"); 236 print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>"; 237 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 238 if ($flowopcnt{$flowop, $dataset}) { 239 printf HTML ("<td>%d</td>\n", $flow_cpu{$flowop, 240 $dataset} / $flowopcnt{$flowop, $dataset}); 241 } else { 242 printf HTML ("<td></td>"); 243 } 244 } 245 print HTML "</i></tr>"; 246 } 247 } 248 print HTML "</table>"; 249 250 end_html();