File: blockbench.pl

package info (click to toggle)
dc3dd 7.3.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,780 kB
  • sloc: ansic: 29,526; sh: 6,778; perl: 1,468; yacc: 1,235; makefile: 151; python: 39; sed: 16
file content (109 lines) | stat: -rw-r--r-- 2,401 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/perl

# blockbench.pl - block-size benchmarking script
# DC3/DCCI
# Andrew Medico <andrew.medico.ctr@dc3.mil>

use strict;
use warnings;

use Getopt::Long;

my $num_trials = 3;
my $sectors = 10000;
my $dd = "/usr/local/bin/dc3dd";

my $help = 0;

my $res = GetOptions("trials=i"  => \$num_trials,
                     "sectors=i" => \$sectors,
                     "dd=s"      => \$dd,
                     "help"      => \$help);

if ($help || not defined $ARGV[0])
{
    print <<END;
Usage: $0 [OPTIONS] device

dc3dd Block Size Benchmark
This script attempts to find the optimum block size for drive imaging by trying
a range of block size values.

  --dd=PATH    Use dc3dd binary PATH [default: /usr/local/bin/dc3dd]
  --trials=N   Average the times of N trials [default: 3]
  --sectors=N  Read N sectors. Increase for fast devices if trials complete
               too quickly for accurate timing, and decrease for slow devices
               if trials take too long. [default: 10000]
  --help       Show this help
END
exit;
}

my $dev = $ARGV[0];

my $pc = $sectors * 10;
my @sizes = qw(512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576);
my %rates;


print "Testing $dev:\n";
print "Trials: $num_trials\n";
print "Sectors: $sectors\n";
print "\n";

my $direct_opt = "";
if ($^O !~ /darwin/i)
{
    $direct_opt = "iflag=direct";
}

# for each candidate size
for my $size (@sizes)
{
    print "bs=$size, trial";
    my @trials;
    # do multiple trials for a good average
    for (1 .. $num_trials)
    {
        print " $_"; 
        my $out = `$dd if=$dev of=/dev/null bs=$size $direct_opt conv=sync,noerror count=$sectors progresscount=$pc 2>&1`;
        # 102400000 bytes (98 M) copied (100%), 0.803168 s, 122 M/s
        if ($out =~ /(\d+) bytes .+ (\d+\.\d+) s/)
        {
            push(@trials, $1/$2);
        }
        else
        {
            die "\ndc3dd execution failed - output was:\n$out\n";
        }
    }
    print "\n";

    $rates{$size} = average(@trials);
}

print "\nResults:\n";

my ($bs, $rate, $speedup);

format STDOUT =
bs=@#######, avg rate @######### B/s (@#X)
$bs, $rate, $speedup
.

my $base = $rates{512};

for $bs (sort {$rates{$b} <=> $rates{$a}} keys %rates)
{
    $rate = $rates{$bs};
    $speedup = $rate / $base;
    write;
}

sub average
{
    my $total = 0;
    map { $total += $_} @_;
    return $total / ($#_+1);
}