/* * Runs a series of tests that randomly access a file. */ #include #include #include #include #include #include #include #include #include #include #define FILE_NAME "/local/large_file" #define ITERATIONS 1000000 #define MAX_BLOCK_SIZE 262144 char block[MAX_BLOCK_SIZE]; void run(int fd, struct stat *fsp, int read_size, int block_size) { struct timeval tv; size_t size; long npages, nsplays, opages, osplays; off_t largest_off, off, smallest_off; int64_t end, start; int i; printf(" read size: %d\n", read_size); largest_off = 0; smallest_off = fsp->st_size; size = sizeof(osplays); sysctlbyname("debug.counter.7", &osplays, &size, NULL, 0); assert(size == sizeof(osplays)); size = sizeof(opages); sysctlbyname("debug.counter.8", &opages, &size, NULL, 0); assert(size == sizeof(opages)); gettimeofday(&tv, NULL); start = 1000000L * tv.tv_sec + tv.tv_usec; for (i = 0; i < ITERATIONS; i++) { off = (random() % (fsp->st_size / block_size)) * block_size; assert((off & (block_size - 1)) == 0); if (off < smallest_off) smallest_off = off; if (off > largest_off) largest_off = off; if (lseek(fd, off, SEEK_SET) != off) err(1, "lseek"); if (read(fd, block, read_size) != read_size) err(1, "read"); } gettimeofday(&tv, NULL); end = 1000000L * tv.tv_sec + tv.tv_usec; size = sizeof(nsplays); sysctlbyname("debug.counter.7", &nsplays, &size, NULL, 0); assert(size == sizeof(nsplays)); size = sizeof(npages); sysctlbyname("debug.counter.8", &npages, &size, NULL, 0); assert(size == sizeof(npages)); /* * Perform a sanity check on the smallest and largest blocks accessed. */ if (smallest_off > fsp->st_size / 100) printf("Warning: smallest off accessed: %ld\n", smallest_off); if (largest_off < fsp->st_size - (fsp->st_size / 100)) printf("Warning: largest off accessed: %ld\n", largest_off); printf(" splays: %ld\n", nsplays - osplays); printf(" pages/splay: %f\n", (double)(npages - opages) / (nsplays - osplays)); printf(" usecs/read: %f\n", (double)(end - start) / ITERATIONS); } main(int argc, char **argv) { struct stat fs; int block_size, fd; fd = open(FILE_NAME, O_RDONLY); if (fd == -1) err(1, "open"); if (fstat(fd, &fs) == -1 || !S_ISREG(fs.st_mode)) err(1, "fstat"); printf("file size: %ld\n", fs.st_size); for (block_size = 4096; block_size <= MAX_BLOCK_SIZE; block_size <<= 1) { printf("block size: %d\n", block_size); run(fd, &fs, 1, block_size); run(fd, &fs, block_size, block_size); } }