#!/usr/bin/perl # ## data sets: 100 / 1000 / 10000 / 100000 files ## 1/10 as many directories as files ## Passes, in order: ## 1 - Create directories via synthesis ## 2 - Create files via synthesis ## 3 - Append to files via recursive descent (find) ## 4 - Read from files via recursive descent (find) ## 5 - Truncate files via recursive descent (find) ## 6 - Stat files via recursive descent (find) ## 7 - Append to files via synthesis ## 8 - Read from files via synthesis ## 9 - Truncate files via synthesis ## 10 - Stat files via synthesis ## 11 - Delete files via synthesis ## 12 - Delete directories via synthesis $NEEDSPACE = 220000; # minimum space required to run tests FIXME - implement $DISKSPACE = 0; # space remaining on partition $NFILES = 0; $NDIRS = 0; $DB = 0; %T = (); # hashed on size of data set, lists of timings for passes $UNAME = ""; # uname -mnrs output $NCPU = 0; # number of cpus detected $CPUTYPE = ""; # type of cpu $CPUSPEED = 0; # speed of cpu @PASSES = ( "", "Create directories via linear synthesis", "Create files via synthesis", "Append to files via recursive descent (find)", "Read from files via recursive descent (find)", "Truncate files via recursive descent (find)", "Stat files via recursive descent (find)", "Append to files via semi-random synthesis", "Read from files via semi-random synthesis", "Truncate files via semi-random synthesis", "Stat files via semi-random synthesis", "Delete files via semi-random synthesis", "Delete directories via linear synthesis" ); sub mkerr { my ( $arg1, $arg2 ) = @_; print ( "$arg1: $arg2\n" ); exit(1); } sub did2path { my ( $id, $path ) = ( $_[0], "" ); if ( ( $id % 2 ) == 0 ) { $path = "lz/"; } else { $path = "rz/"; } $id = int ( $id / 2 ); print ("(pre) id = $id path = $path\n") if ( $DB ); while ( $id != 0 ) { if ( ( $id % 2 ) == 0 ) { $path = "lz/".$path; } else { $path = "rz/".$path; } print ("id = $id path = $path\n") if ( $DB ); $id = int ( $id / 2 ); } $path = "fsdir/".$path; return $path; } sub fid2path { my ( $id, $path ) = ( $_[0], "" ); $path = did2path ( $id % $NDIRS ); if ( $id % 3 == 0 ) { $path .= "j$id"; } elsif ( $id % 3 == 1 ) { $path .= "n$id"; } else { $path .= "t$id"; } return $path; } sub inspect_platform { my ( $dbuf, $scratch ); $UNAME = `uname -mnrs`; $NCPU = 1; if ( $UNAME =~ /[Ll]inux/ ) { $scratch = $dbuf = `cat /proc/cpuinfo`; $NCPU = ( $scratch =~ s/^processor\s+:/$1/sg ); if ( $NCPU < 1 ) { $NCPU = 1; } if ( $dbuf =~ /model name[^:]+: ([^\n]+)/s ) { $CPUTYPE = $1; } elsif ( $dbuf =~ /cpu[^:]+: ([^\n]+)/s ) { $CPUTYPE = $1; } else { $CPUTYPE = "Unknown"; } if ( $dbuf =~ /cpu MHz\s+:\s*([0-9]+)/ ) { $CPUSPEED = $1; } elsif ( $dbuf =~ /bogomips[^:]+: ([0-9\.]+)/ ) { $CPUSPEED = int ( $1 + 0.5 ); if ( $CPUTYPE =~ /[34]86/ ) { $CPUSPEED *= 2; } elsif ( $CPUTYPE =~ /586/ ) { $CPUSPEED = int ( ( $CPUSPEED * 2.5 ) + 0.5 ); } elsif ( $CPUTYPE =~ /686/ ) { # i686 has same BogoMIPS rate as MHz } elsif ( $CPUTYPE =~ /K(.?)6/ ) { # this is right for K6-2, not sure about others $CPUSPEED = int ( $CPUSPEED / 2 ); } else { $CPUSPEED .= "?"; } } else { $CPUSPEED = "Unknown"; } } # end of if linux elsif ( $UNAME =~ /[Ff]ree[Bb][Ss][Dd]/ ) { $CPUTYPE = "Unknown"; $CPUSPEED = "Unknown"; $dbuf = `grep CPU: /var/log/messages`; $dbuf .= `dmesg | grep CPU: 1>&2`; if ( $dbuf =~ /CPU: (.*?) \(([0-9\.]+)-MHz (.*?)-class/ ) { # might want to switch to $CPUTYPE = $1 $CPUTYPE = $3; $CPUSPEED = int ( $2 + 0.5 ); } } # end of inspecting uname output # FIXME -- write detection code for other platforms } # end of sub inspect_platform() sub describe_platform { print ("$UNAME"); print ("$NCPU x $CPUSPEED MHz $CPUTYPE\n"); } sub pass01 { # Create directories via synthesis my ( $i, $path ); mkdir ( "fsdir", 0700 ); if ( !-d "fsdir" ) { mkerr ( "pass01", $! ); } for ( $i = 0; $i < $NDIRS; $i++ ) { $path = did2path ( $i ); print ("creating directory $i = $path\n") if ( $DB ); mkdir ( $path, 0700 ); if ( !-d $path ) { mkerr ( "pass01", $! ); } } } sub pass02 { # Create files via synthesis my ( $i, $path, $res ); for ( $i = 0; $i < $NFILES; $i++ ) { $path = fid2path ( $i ); open ( F, ">$path" ) or mkerr ( "pass02", $res ); close ( F ); } } sub pass03 { # Append to files via recursive descent (find) my ( $fname, $tmp ); $fname = $ENV{"PWD"} . "/data"; if ( !-e $fname ) { open ( F, ">$fname" ) or mkerror ( "pass03", $! ); print ( F "#"x1097 ); close ( F ); } $tmp = `find fsdir -type f -exec cat $fname >> {} \\;`; unlink ( $fname ); } sub pass04 { # Read from files via recursive descent (find) my ( $fname, $tmp ); $fname = $ENV{"PWD"} . "/junk"; $tmp = `find fsdir -type f -exec cat {} \> $fname \\;`; unlink ( $fname ); } sub pass05 { # Truncate files via recursive descent (find) my ( $tmp ); $tmp = `find fsdir -type f -exec echo \> {} \\;`; } sub pass06 { # Stat files via recursive descent (find) my ( $tmp ); $tmp = `find fsdir -type f -links +0 -exec true \\;`; } sub pass07 { # Append to files via semi-random synthesis my ( $i, $j, $path, $buf ); $buf = "X"x1097; for ( $i = 0, $j = 0; $i < $NFILES; $i++ ) { $path = fid2path ( $j ); open ( F, ">>$path" ) or mkerr ( "pass07", $! ); syswrite ( F, $buf ); close ( F ); $j += 1056563; $j %= $NFILES; } } sub pass08 { # Read from files via semi-random synthesis my ( $i, $j, $path, $buf ); for ( $i = 0, $j = 0; $i < $NFILES; $i++ ) { $path = fid2path ( $j ); open ( F, "<$path" ) or mkerr ( "pass08", $! ); sysread(F,$buf,1097); close ( F ); $j += 1058107; $j %= $NFILES; } } sub pass09 { # Truncate files via semi-random synthesis my ( $i, $j, $path ); for ( $i = 0, $j = 0; $i < $NFILES; $i++ ) { $path = fid2path ( $j ); open ( F, ">$path" ) or mkerr ( "pass09", $! ); close ( F ); $j += 1060061; $j %= $NFILES; } } sub pass10 { # Stat files via semi-random synthesis my ( $i, $j, $path, @astat ); for ( $i = 0, $j = 0; $i < $NFILES; $i++ ) { $path = fid2path ( $j ); @astat = stat ( $path ); $j += 1070039; $J %= $NFILES; } } sub pass11 { # Delete files via semi-random synthesis my ( $i, $j, $path ); for ( $i = 0, $j = 0; $i < $NFILES; $i++ ) { $path = fid2path ( $j ); unlink ( $path ) or mkerr ( "pass11", $! ); $j += 1080007; $j %= $NFILES; } } sub pass12 { # Delete directories via linear synthesis my ( $i, $path ); for ( $i = $NDIRS-1; $i >= 0; $i-- ) { $path = did2path ( $i ); rmdir ( $path ) or mkerr ( "pass12", $! ); } rmdir ( "fsdir" ); } sub run_one_test { my ( $pass ); $pass = int($_[0]); if ( ( $pass < 1 ) || ( $pass > 12 ) ) { return "error"; } if ( $pass < 10 ) { $pass = "0" . $pass; } $pass = "pass" . $pass . "();"; $btime = time(); while ( time() == $btime ){}; $btime = time(); eval ( $pass ); $etime = time(); return ( $etime - $btime ); } sub pad { my ( $str, $pad ) = @_; return " "x($pad-length($str)).$str; } sub run_one_set { my ( $i, $t ); $NFILES = $_[0]; $NDIRS = int ( $NFILES / 10 ); for ( $i = 1; $i <= 12; $i++ ) { $t = pad ( $i, 2 ); print ("running pass $t (data set $NFILES) ".$PASSES[$i]."\n"); $T{$NFILES}[$i] = run_one_test ( $i ); } } sub display_times { my ( $i ); print (" number of files per pass\n"); print (" pass"); foreach $key ( sort ( keys ( %T ) ) ) { print (" ".pad($key,6)); } print ("\n"); for ( $i = 1; $i <= 12; $i++ ) { print ( pad($i,5)." "); foreach $key ( sort ( keys ( %T ) ) ) { print (pad($T{$key}[$i],6)." "); } print (" ".$PASSES[$i]."\n"); } } # Main block inspect_platform(); describe_platform(); run_one_set ( 10000 ); run_one_set ( 30000 ); run_one_set ( 90000 ); # run_one_set ( 70000 ); # run_one_set ( 100000 ); describe_platform(); display_times(); 1;