#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <fcntl.h>
#include <libutil.h>
#define BLKSIZE ((intmax_t)1024)
#define BLKMASK (BLKSIZE - 1)
char Buf[BLKSIZE];
int
main(int ac, char **av)
{
struct timeval tv1;
struct timeval tv2;
off_t bytes;
off_t base;
off_t skip;
intmax_t us;
int fd;
int count;
if (ac == 1) {
fprintf(stderr, "seekbench <blockdevice>\n");
exit(1);
}
fd = open(av[1], O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
lseek(fd, 0L, 2);
bytes = lseek(fd, 0L, 1);
printf("%s: %jdMB\n", av[1], (intmax_t)bytes / 1024 / 1024);
printf("distance avg-seek\n");
skip = BLKSIZE;
while (skip < bytes) {
count = 0;
gettimeofday(&tv1, NULL);
for (base = skip; base < bytes && count < 100; base += skip) {
lseek(fd, base, 0);
read(fd, Buf, BLKSIZE);
++count;
}
gettimeofday(&tv2, NULL);
us = (tv2.tv_usec + 1000000 - tv1.tv_usec) +
(tv2.tv_sec - 1 - tv1.tv_sec) * 1000000;
if (skip < 100*1024*1024)
printf("%5jdKB %6.3fms\n",
(intmax_t)skip / 1024,
(double)us / 1000.0 / count);
else
printf("%5jdMB %6.3fms\n",
(intmax_t)skip / 1024 / 1024,
(double)us / 1000.0 / count);
skip += BLKSIZE;
if (skip < BLKSIZE * 25)
skip += BLKSIZE;
else
skip += (skip / 25 + BLKMASK) & ~BLKMASK;
}
}