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 35use CGI ':standard'; 36 37$maxiopsoverall = 0; 38$maxiopsrate = 0; 39$maxbandwidth = 0; 40 41# 42# Create html and text 43# 44open (HTML, ">index.html"); 45print HTML start_html(-title=>'Filebench'); 46print HTML "<body>"; 47# 48# Print aggregate flowop stats 49# 50foreach $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 130print HTML h1('Throughput breakdown (ops per second)'); 131print HTML "<table border=1>"; 132print HTML "<b><td>Workload</td>"; 133foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 134 print HTML "<td>$desc{$dataset}</td>"; 135} 136print HTML "</b></tr>"; 137 138foreach $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} 155print HTML "</table>"; 156 157# HTML Bandwidth 158print HTML h1('Bandwidth breakdown (MB/s)'); 159print HTML "<table border=1>"; 160print HTML "<td>Workload</td>"; 161foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 162 print HTML "<td>$desc{$dataset}</td>"; 163} 164print HTML "</tr>"; 165foreach $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} 177print HTML "</table>"; 178 179# HTML Latency 180print HTML h1('Latency breakdown (ms per op)'); 181print HTML "<table border=1>"; 182print HTML "<td>Workload</td>"; 183foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 184 print HTML "<td>$desc{$dataset}</td>"; 185} 186 187print HTML "</tr>"; 188foreach $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} 213print HTML "</table>"; 214 215# HTML Efficiency 216print HTML h1('Efficiency breakdown (Code path length in uS/op)'); 217print HTML "<table border=1>"; 218print HTML "<td>Workload</td>"; 219foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 220 print HTML "<td>$desc{$dataset}</td>"; 221} 222print HTML "</tr>"; 223foreach $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} 248print HTML "</table>"; 249 250end_html(); 251