Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 94 lines (74 sloc) 2.217 kb
2fc5974 @fidlej Added portable seeker.
authored
1 #!/usr/bin/env python
2 """Usage: seeker.py /path/to/raw/device
eff8071 @fidlej Improved wording.
authored
3 Measures the possible number of seeks per second.
2fc5974 @fidlej Added portable seeker.
authored
4 """
8b54cbc @fidlej Got the file size by halving if needed.
authored
5 # It should work on any Unix.
6 # It is based on the Linux specific seeker.c from:
7 # http://www.linuxinsight.com/how_fast_is_your_disk.html
2fc5974 @fidlej Added portable seeker.
authored
8
9 import os
10 import sys
11 import time
12 import random
13
14 BLOCKSIZE = 512
db2927f @fidlej Made it more python2.4 comptabile.
authored
15 SEEK_END = 2
2fc5974 @fidlej Added portable seeker.
authored
16
17 def _get_size(input):
db2927f @fidlej Made it more python2.4 comptabile.
authored
18 input.seek(0, SEEK_END)
8b54cbc @fidlej Got the file size by halving if needed.
authored
19 size = input.tell()
20 if size != 0:
21 return size
22
23 # FreeBSD does not support SEEK_END on devices.
24 # We need to get the size by binary halving.
25 pos = 0
26 step = 2**40 # 1TB
27 while True:
28 pos += step
29 try:
30 input.seek(pos)
31 data = input.read(1)
32 except IOError, possible:
33 data = ""
34
35 if len(data) != 1:
36 if step == 1:
37 # Size is the possible position + 1.
38 return (pos - step) + 1
39
40 pos -= step
41 step = max(1, step // 2)
2fc5974 @fidlej Added portable seeker.
authored
42
43
44 def _seek_randomly(dev, size, num_seeks):
45 num_blocks = size // BLOCKSIZE
46 for i in xrange(num_seeks):
47 block = random.randrange(num_blocks)
48 dev.seek(block * BLOCKSIZE)
8b54cbc @fidlej Got the file size by halving if needed.
authored
49 data = dev.read(BLOCKSIZE)
50 assert len(data) == BLOCKSIZE
2fc5974 @fidlej Added portable seeker.
authored
51
52
2741080 @fidlej Incremented the number of tried seeks over time to have an anytime test.
authored
53 def _benchmark_seek(dev, size, num_seeks):
54 start = time.time()
55 _seek_randomly(dev, size, num_seeks)
56 end = time.time()
57
58 duration = end - start
532d255 @fidlej Prevented a division by zero.
authored
59 if duration > 0:
60 rate = int(num_seeks/float(duration))
61 else:
62 rate = float("inf")
63
2741080 @fidlej Incremented the number of tried seeks over time to have an anytime test.
authored
64 print "%s/%.2f = %s seeks/second" % (
532d255 @fidlej Prevented a division by zero.
authored
65 num_seeks, duration, rate)
2741080 @fidlej Incremented the number of tried seeks over time to have an anytime test.
authored
66 print "%.2f ms random access time" % (1000 * duration/float(num_seeks))
67
68
2fc5974 @fidlej Added portable seeker.
authored
69 def main():
70 args = sys.argv[1:]
71 if len(args) != 1:
72 print >>sys.stderr, __doc__
73 sys.exit(1)
74
75 filename = args[0]
76 dev = open(filename)
77 size = _get_size(dev)
2741080 @fidlej Incremented the number of tried seeks over time to have an anytime test.
authored
78 if size < BLOCKSIZE:
79 print >>sys.stderr, (
80 "too small file: %s bytes" % size)
81 sys.exit(1)
82
58a81cf @fidlej Used GB in the display.
authored
83 print "Benchmarking %s [%.2f GB]" % (filename, size/float(2**30))
2fc5974 @fidlej Added portable seeker.
authored
84
85 random.seed()
2741080 @fidlej Incremented the number of tried seeks over time to have an anytime test.
authored
86 base = 10
87 for power in xrange(1, 6):
88 num_seeks = base**power
89 _benchmark_seek(dev, size, num_seeks)
2fc5974 @fidlej Added portable seeker.
authored
90
91
92 if __name__ == "__main__":
93 main()
Something went wrong with that request. Please try again.