1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#! @PERL@ 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- Valgrind performance testing script vg_perf ---## 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# This file is part of Valgrind, a dynamic binary instrumentation 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# framework. 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Copyright (C) 2005 Nicholas Nethercote 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# njn@valgrind.org 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# This program is free software; you can redistribute it and/or 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# modify it under the terms of the GNU General Public License as 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# published by the Free Software Foundation; either version 2 of the 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# License, or (at your option) any later version. 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# This program is distributed in the hope that it will be useful, but 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# WITHOUT ANY WARRANTY; without even the implied warranty of 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# General Public License for more details. 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# You should have received a copy of the GNU General Public License 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# along with this program; if not, write to the Free Software 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 02111-1307, USA. 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# The GNU General Public License is contained in the file COPYING. 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# usage: see usage message. 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# You can specify individual files to test, or whole directories, or both. 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Directories are traversed recursively, except for ones named, for example, 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# CVS/ or docs/. 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Each test is defined in a file <test>.vgperf, containing one or more of the 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# following lines, in any order: 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - prog: <prog to run> (compulsory) 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - args: <args for prog> (default: none) 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - vgopts: <Valgrind options> (default: none) 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - prereq: <prerequisite command> (default: none) 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - cleanup: <post-test cleanup cmd to run> (default: none) 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# The prerequisite command, if present, must return 0 otherwise the test is 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# skipped. 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse warnings; 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse strict; 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Global vars 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $usage = <<END 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownusage: vg_perf [options] [files or dirs] 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown options for the user, with defaults in [ ], are: 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -h --help show this message 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --reps=<n> number of repeats for each program [1] 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --tools=<t1,t2,t3> tools to run [Nulgrind and Memcheck] 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --vg Valgrind(s) to measure (can be specified multiple 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown times). The "in-place" build is used. 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [Valgrind in the current directory] 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Any tools named in --tools must be present in all directories specified 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown with --vg. (This is not checked.) 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEND 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown; 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Test variables 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $vgopts; # valgrind options 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $prog; # test prog 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $args; # test prog args 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $prereq; # prerequisite test to satisfy before running test 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $cleanup; # cleanup command to run 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Command line options 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $n_reps = 1; # Run each test $n_reps times and choose the best one. 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @vgdirs; # Dirs of the various Valgrinds being measured. 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @tools = ("none", "memcheck"); # tools being measured 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $num_tests_done = 0; 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $num_timings_done = 0; 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Starting directory 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchomp(my $tests_dir = `pwd`); 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Process command line, setup 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# If $prog is a relative path, it prepends $dir to it. Useful for two reasons: 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 1. Can prepend "." onto programs to avoid trouble with users who don't have 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# "." in their path (by making $dir = ".") 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 2. Can prepend the current dir to make the command absolute to avoid 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# subsequent trouble when we change directories. 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Also checks the program exists and is executable. 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub validate_program ($$$$) 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($dir, $prog, $must_exist, $must_be_executable) = @_; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If absolute path, leave it alone. If relative, make it 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # absolute -- by prepending current dir -- so we can change 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # dirs and still use it. 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $prog = "$dir/$prog" if ($prog !~ /^\//); 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($must_exist) { 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (-f $prog) or die "vg_perf: '$prog' not found or not a file ($dir)\n"; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($must_be_executable) { 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (-x $prog) or die "vg_perf: '$prog' not executable ($dir)\n"; 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $prog; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub add_vgdir($) 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($vgdir) = @_; 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($vgdir !~ /^\//) { $vgdir = "$tests_dir/$vgdir"; } 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown validate_program($vgdir, "./coregrind/valgrind", 1, 1); 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@vgdirs, $vgdir); 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub process_command_line() 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @fs; 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for my $arg (@ARGV) { 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($arg =~ /^-/) { 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($arg =~ /^--reps=(\d+)$/) { 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $n_reps = $1; 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($n_reps < 1) { die "bad --reps value: $n_reps\n"; } 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--vg=(.+)$/) { 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Make dir absolute if not already 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_vgdir($1); 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--tools=(.+)$/) { 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @tools = split(/,/, $1); 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die $usage; 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@fs, $arg); 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If no --vg options were specified, use the current tree. 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == @vgdirs) { 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_vgdir($tests_dir); 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (0 != @fs) or die "No test files or directories specified\n"; 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return @fs; 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Read a .vgperf file 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub read_vgperf_file($) 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($f) = @_; 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Defaults. 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ($vgopts, $prog, $args, $prereq, $cleanup) 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = ("", undef, "", undef, undef, undef, undef); 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown open(INPUTFILE, "< $f") || die "File $f not openable\n"; 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (my $line = <INPUTFILE>) { 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($line =~ /^\s*#/ || $line =~ /^\s*$/) { 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown next; 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($line =~ /^\s*vgopts:\s*(.*)$/) { 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $vgopts = $1; 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($line =~ /^\s*prog:\s*(.*)$/) { 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $prog = validate_program(".", $1, 1, 1); 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($line =~ /^\s*args:\s*(.*)$/) { 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $args = $1; 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($line =~ /^\s*prereq:\s*(.*)$/) { 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $prereq = $1; 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($line =~ /^\s*cleanup:\s*(.*)$/) { 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $cleanup = $1; 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die "Bad line in $f: $line\n"; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown close(INPUTFILE); 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!defined $prog) { 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $prog = ""; # allow no prog for testing error and --help cases 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == @tools) { 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die "vg_perf: missing 'tools' line in $f\n"; 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Do one test 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Since most of the program time is spent in system() calls, need this to 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# propagate a Ctrl-C enabling us to quit. 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub mysystem($) 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($cmd) = @_; 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $retval = system($cmd); 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($retval == 2) { 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exit 1; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $retval; 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Run program N times, return the best user time. Use the POSIX 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# -p flag on /usr/bin/time so as to get something parseable on AIX. 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub time_prog($$) 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($cmd, $n) = @_; 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmin = 999999; 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (my $i = 0; $i < $n; $i++) { 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mysystem("echo '$cmd' > perf.cmd"); 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $retval = mysystem("$cmd > perf.stdout 2> perf.stderr"); 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (0 == $retval) or 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die "\n*** Command returned non-zero ($retval)" 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown . "\n*** See perf.{cmd,stdout,stderr} to determine what went wrong.\n"; 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $out = `cat perf.stderr`; 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ($out =~ /[Uu]ser +([\d\.]+)/) or 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die "\n*** missing usertime in perf.stderr\n"; 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tmin = $1 if ($1 < $tmin); 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Avoid divisions by zero! 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (0 == $tmin ? 0.01 : $tmin); 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub do_one_test($$) 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($dir, $vgperf) = @_; 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $vgperf =~ /^(.*)\.vgperf/; 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $name = $1; 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my %first_tTool; # For doing percentage speedups when comparing 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # multiple Valgrinds 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown read_vgperf_file($vgperf); 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $prereq) { 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (system("$prereq") != 0) { 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("%-16s (skipping, prereq failed: $prereq)\n", "$name:"); 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $timecmd = "/usr/bin/time -p"; 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Do the native run(s). 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("-- $name --\n") if (@vgdirs > 1); 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $cmd = "$timecmd $prog $args"; 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tNative = time_prog($cmd, $n_reps); 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $vgdir (@vgdirs) { 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Benchmark name 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("%-8s ", $name); 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print the Valgrind version if we are measuring more than one. 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $vgdirname = $vgdir; 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chomp($vgdirname = `basename $vgdir`); 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("%-10s:", $vgdirname); 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Native execution time 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("%4.2fs", $tNative); 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $tool (@tools) { 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # First two chars of toolname for abbreviation 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tool_abbrev = $tool; 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tool_abbrev =~ s/(..).*/$1/; 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Do the tool run(s). Set both VALGRIND_LIB and VALGRIND_LIB_INNER 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # in case this Valgrind was configured with --enable-inner. And 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # also VALGRINDLIB, which was the old name for the variable, to 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # allow comparison against old Valgrind versions (eg. 2.4.X). 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf(" %s:", $tool_abbrev); 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $vgsetup = "VALGRINDLIB=$vgdir/.in_place " 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown . "VALGRIND_LIB=$vgdir/.in_place " 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown . "VALGRIND_LIB_INNER=$vgdir/.in_place "; 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $vgcmd = "$vgdir/coregrind/valgrind " 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown . "--command-line-only=yes --tool=$tool -q " 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown . "--memcheck:leak-check=no " 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown . "--trace-children=yes " 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown . "$vgopts "; 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $cmd = "$vgsetup $timecmd $vgcmd $prog $args"; 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tTool = time_prog($cmd, $n_reps); 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("%4.1fs (%4.1fx,", $tTool, $tTool/$tNative); 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If it's the first timing for this tool on this benchmark, 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # record the time so we can get the percentage speedup of the 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # subsequent Valgrinds. Otherwise, compute and print 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # the speedup. 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (not defined $first_tTool{$tool}) { 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $first_tTool{$tool} = $tTool; 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" -----)"); 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $speedup = 100 - (100 * $tTool / $first_tTool{$tool}); 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("%5.1f%%)", $speedup); 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $num_timings_done++; 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $cleanup) { 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (system("$cleanup") == 0) or 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" ($name cleanup operation failed: $cleanup)\n"); 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("\n"); 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $num_tests_done++; 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Test one directory (and any subdirs) 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub test_one_dir($$); # forward declaration 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub test_one_dir($$) 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($dir, $prev_dirs) = @_; 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $dir =~ s/\/$//; # trim a trailing '/' 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chomp(my $initial_dir = `pwd`); # record where we started 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Ignore dirs into which we should not recurse. 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($dir =~ /^(BitKeeper|CVS|SCCS|docs|doc)$/) { return; } 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chdir($dir) or die "Could not change into $dir\n"; 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Nb: Don't prepend a '/' to the base directory 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $full_dir = $prev_dirs . ($prev_dirs eq "" ? "" : "/") . $dir; 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $dashes = "-" x (50 - length $full_dir); 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @fs = glob "*"; 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $found_tests = (0 != (grep { $_ =~ /\.vgperf$/ } @fs)); 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($found_tests) { 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "-- Running tests in $full_dir $dashes\n"; 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $f (@fs) { 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (-d $f) { 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown test_one_dir($f, $full_dir); 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($f =~ /\.vgperf$/) { 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_one_test($full_dir, $f); 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($found_tests) { 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "-- Finished tests in $full_dir $dashes\n"; 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chdir("$initial_dir"); 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Summarise results 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub summarise_results 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("\n== %d programs, %d timings =================\n\n", 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $num_tests_done, $num_timings_done); 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# main() 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# nuke VALGRIND_OPTS 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown$ENV{"VALGRIND_OPTS"} = ""; 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @fs = process_command_line(); 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownforeach my $f (@fs) { 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (-d $f) { 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown test_one_dir($f, ""); 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Allow the .vgperf suffix to be given or omitted 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($f =~ /.vgperf$/ && -r $f) { 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # do nothing 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (-r "$f.vgperf") { 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $f = "$f.vgperf"; 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die "`$f' neither a directory nor a readable test file/name\n" 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $dir = `dirname $f`; chomp $dir; 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $file = `basename $f`; chomp $file; 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chdir($dir) or die "Could not change into $dir\n"; 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_one_test($dir, $file); 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chdir($tests_dir); 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsummarise_results(); 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- end ---## 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 400