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 2007 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 ($prefix, $workload, $fstype) = split(/\./, $file); 61 $dataset = $dir; 62 $dataset =~ s/.*\/(.+)$/$1/; 63 $dataset =~ s/\/$//; 64 $desc{$dataset} = "$description"; 65# print "dataset = $dataset\n"; 66# print "workload = $workload\n"; 67# print "fstype = $fstype\n"; 68 open (STATS, $file); 69 $tmp = <STATS>; 70 while (<STATS>) { 71 ($flowop, $ops, $bandwidth, $latency, $cpu, $wait, $seconds) = split(/[ \t]+/, $_); 72 73 if (/^$/) { 74 $tmp = <STATS>; 75 ($fluff, $opcnt, $ops, $reads, $writes, $bandwidth, 76 $cpu) = split(/[ \tA-z:\/,]+/, $tmp); 77 $ops{$workload, $dataset} = $ops; 78 last; 79 } 80 81 $ops =~ s/ops\/s//; 82 $bandwidth =~ s/mb\/s//; 83 $latency =~ s/ms\/op//; 84 $cpu =~ s/us\/op//; 85 86 # Collapse shadow reads into single metric 87 if ($flowop =~ /shadowread/) { 88 $flowop = "shadow-read"; 89 } 90 91 # Collapse database writes into single metric 92 if ($flowop =~ /db.*write/) { 93 $flowop = "db-write"; 94 } 95 96 # Collapse database writes into single metric 97 if ($flowop =~ /db.*write/) { 98 $flowop = "db-write"; 99 } 100 101 $datasets{$dataset} = $dataset; 102 $workloads{$workload} = $workload; 103 104 $flowops{$flowop} = $flowop; 105 $wkl_flowops{$flowop, $workload} = $flowop; 106 $wkl_workload{$flowop, $workload} = $workload; 107 $flow_ops{$flowop, $workload, $dataset} += $ops; 108 $flow_bandwidth{$flowop, $workload, $dataset} += $bandwidth; 109 $flow_latency{$flowop, $workload, $dataset} += $latency; 110 $flow_cpu{$flowop, $workload, $dataset} += $cpu; 111 112 $bandwidth{$workload, $dataset} += $bandwidth; 113 $latency{$workload, $dataset} += $latency; 114 $cpu{$workload, $dataset} += $cpu; 115 116 $flowopcnt{$flowop, $workload, $dataset}++; 117 $workloadcnt{$workload, $dataset}++; 118 } 119 close(STATS); 120 } 121} 122 123# HTML IOPS 124print HTML h1('Throughput breakdown (ops per second)'); 125print HTML "<table border=1>"; 126print HTML "<b><td>Workload</td>"; 127foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 128 print HTML "<td>$desc{$dataset}</td>"; 129} 130print HTML "</b></tr>"; 131 132foreach $workload (sort (keys %workloads)) { 133 print HTML "<b><tr><td>$workload</td>"; 134 $last = 0; 135 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 136 $color = "white"; 137 $this = $ops{$workload, $dataset}; 138 if ($last && ($this - $last) < ($last * -0.1)) { 139 $color = "red"; 140 } 141 if ($last && ($this - $last) > ($last * 0.1)) { 142 $color = "green"; 143 } 144 printf HTML ("<td>%d</td\n", $this); 145 $last = $ops{$workload, $dataset}; 146 } 147 print HTML "</b></tr>"; 148} 149print HTML "</table>"; 150 151# HTML Bandwidth 152print HTML h1('Bandwidth breakdown (MB/s)'); 153print HTML "<table border=1>"; 154print HTML "<td>Workload</td>"; 155foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 156 print HTML "<td>$desc{$dataset}</td>"; 157} 158print HTML "</tr>"; 159foreach $workload (sort (keys %workloads)) { 160 $bandwidth = 0; 161 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 162 $bandwidth += $bandwidth{$workload, $dataset}; 163 } 164 next if ($bandwidth == 0); 165 print HTML "<tr><td>$workload</td>"; 166 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 167 printf HTML ("<td>%d</td>\n", $bandwidth{$workload, $dataset}); 168 } 169 print HTML "</tr>"; 170} 171print HTML "</table>"; 172 173# HTML Latency 174print HTML h1('Latency breakdown (ms per op)'); 175print HTML "<table border=1>"; 176print HTML "<td>Workload</td>"; 177foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 178 print HTML "<td>$desc{$dataset}</td>"; 179} 180 181print HTML "</tr>"; 182foreach $workload (sort (keys %workloads)) { 183 print HTML "<tr><td>$workload</td>"; 184 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 185 if ( $workloadcnt{$workload, $dataset}) { 186 printf HTML ("<td>%.1f</td>", $latency{$workload, 187 $dataset} / $workloadcnt{$workload, $dataset}); 188 } else { 189 printf HTML ("<td></td>"); 190 } 191 } 192 print HTML "</tr>"; 193 foreach $flowop (keys %wkl_flowops) { 194 next if ("$wkl_workload{$flowop}" ne "$workload"); 195 print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>"; 196 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 197 if ( $flowopcnt{$flowop, $dataset}) { 198 printf HTML ("<td>%.1f</td>\n", $flow_latency{$flowop, 199 $dataset} / $flowopcnt{$flowop, $dataset}); 200 } else { 201 printf HTML ("<td></td>"); 202 } 203 } 204 print HTML "</i></tr>"; 205 } 206} 207print HTML "</table>"; 208 209# HTML Efficiency 210print HTML h1('Efficiency breakdown (Code path length in uS/op)'); 211print HTML "<table border=1>"; 212print HTML "<td>Workload</td>"; 213foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 214 print HTML "<td>$desc{$dataset}</td>"; 215} 216print HTML "</tr>"; 217foreach $workload (sort (keys %workloads)) { 218 print HTML "<tr><td>$workload</td>"; 219 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 220 if ($workloadcnt{$workload, $dataset}) { 221 printf HTML ("<td>%d</td>", $cpu{$workload, $dataset} 222 / $workloadcnt{$workload, $dataset}); 223 } else { 224 printf HTML ("<td></td>"); 225 } 226 } 227 print HTML "</tr>"; 228 foreach $flowop (keys %wkl_flowops) { 229 next if ("$wkl_workload{$flowop}" ne "$workload"); 230 print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>"; 231 foreach $dataset (sort {$a cmp $b}(keys %datasets)) { 232 if ($flowopcnt{$flowop, $dataset}) { 233 printf HTML ("<td>%d</td>\n", $flow_cpu{$flowop, 234 $dataset} / $flowopcnt{$flowop, $dataset}); 235 } else { 236 printf HTML ("<td></td>"); 237 } 238 } 239 print HTML "</i></tr>"; 240 } 241} 242print HTML "</table>"; 243 244end_html(); 245