xref: /dragonfly/test/debug/seekbench.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1 /*
2  * SEEKBENCH.C
3  *
4  * cc seekbench.c -o /tmp/sb
5  *
6  * This intentionally performs a sequence of seek/reads with ever
7  * growing distances in a way that should be essentially uncached.
8  * It attempts to defeat both OS caches and the HDs zone cache.
9  *
10  * The average read-latency per seek/read is calculated.
11  *
12  * This can heat up the hard drive so be careful.
13  */
14 
15 #include <sys/types.h>
16 #include <sys/time.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <stdarg.h>
21 #include <fcntl.h>
22 #include <libutil.h>
23 
24 #define BLKSIZE               ((intmax_t)1024)
25 #define BLKMASK               (BLKSIZE - 1)
26 
27 char Buf[BLKSIZE];
28 
29 int
main(int ac,char ** av)30 main(int ac, char **av)
31 {
32           struct timeval tv1;
33           struct timeval tv2;
34           off_t bytes;
35           off_t base;
36           off_t skip;
37           intmax_t us;
38           int fd;
39           int count;
40 
41           if (ac == 1) {
42                     fprintf(stderr, "seekbench <blockdevice>\n");
43                     exit(1);
44           }
45           fd = open(av[1], O_RDONLY);
46           if (fd < 0) {
47                     perror("open");
48                     exit(1);
49           }
50           lseek(fd, 0L, 2);
51           bytes = lseek(fd, 0L, 1);
52           printf("%s: %jdMB\n", av[1], (intmax_t)bytes / 1024 / 1024);
53           printf("distance avg-seek\n");
54           skip = BLKSIZE;
55           while (skip < bytes) {
56                     count = 0;
57                     gettimeofday(&tv1, NULL);
58                     for (base = skip; base < bytes && count < 100; base += skip) {
59                               lseek(fd, base, 0);
60                               read(fd, Buf, BLKSIZE);
61                               ++count;
62                     }
63                     gettimeofday(&tv2, NULL);
64                     us = (tv2.tv_usec + 1000000 - tv1.tv_usec) +
65                          (tv2.tv_sec - 1 - tv1.tv_sec) * 1000000;
66                     if (skip < 100*1024*1024)
67                               printf("%5jdKB %6.3fms\n",
68                                         (intmax_t)skip / 1024,
69                                         (double)us / 1000.0 / count);
70                     else
71                               printf("%5jdMB %6.3fms\n",
72                                         (intmax_t)skip / 1024 / 1024,
73                                         (double)us / 1000.0 / count);
74                     skip += BLKSIZE;
75                     if (skip < BLKSIZE * 25)
76                               skip += BLKSIZE;
77                     else
78                               skip += (skip / 25 + BLKMASK) & ~BLKMASK;
79           }
80 }
81