Date: Wed, 27 Dec 2006 20:10:46 +1300 From: Mark Kirkwood <markir@paradise.net.nz> To: Mark Kirkwood <markir@paradise.net.nz> Cc: freebsd-performance@freebsd.org Subject: Re: Cached file read performance Message-ID: <45921C76.8020200@paradise.net.nz> In-Reply-To: <458B3651.8090601@paradise.net.nz> References: <458B3651.8090601@paradise.net.nz>
next in thread | previous in thread | raw e-mail | index | archive | help
Mark Kirkwood wrote: > I used the attached program to read a cached > 781MB file sequentially and randomly with a specified block size (see > below). In the interest of making it easy for anyone to re-test this later, I'll in-line the program source here (I did post a link to my web space, but that could get cleaned up by accident...) ------------------------------------------------------------------------------------------- /* * readtest.c: read a file sequentially or randomly */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> #include <sys/uio.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <math.h> void usage(char *prog) { printf("usage %s filename blocksize 1|0 (0 - random, 1 - sequential)\n", prog); return; } int main(int argc, char **argv) { int fd; char *file; struct stat *fileinfo; char *buf; int blocksz; int numblocks, i; off_t offset, offsetmin, offsetmax; double offsetsum, offsetsumx2; int seq; int stats = 0; struct timeval starttp, endtp, elapsedtp; double elapsed; double iorate; if (argc != 4 && argc != 5) { usage(argv[0]); exit(1); } else { if ((file = (char *) malloc(strlen(argv[1]))) == NULL) { printf("out of memory!\n"); exit(2); } strcpy(file, argv[1]); blocksz = atoi(argv[2]); seq = atoi(argv[3]); if (argc == 5) stats = 1; } /* Start timing. */ gettimeofday(&starttp, NULL); if ((fd = open(file, O_RDONLY)) == -1) { /* Can't open the file. */ perror("cannot open"); exit(1); } else { /* How many random sequential access calls are needed? */ fileinfo = (struct stat*) malloc(sizeof(struct stat)); fstat(fd,fileinfo); numblocks = (fileinfo->st_size)/blocksz; free(fileinfo); } /* Allocate buffer. */ buf = (char *) malloc(blocksz); if (buf == NULL) { printf("out of memory!\n"); exit(2); } /* If we are random, initialize. */ if (seq != 1) srandom(2006122111); /* * Read the file sequentially or randomly. * If random then calculate the offset to seek to using the formula: * * offet in blocks = random() % (numblocks - 1) * */ for (i = 0; i < numblocks; i++) { if (seq == 1) { offset = (off_t)i * blocksz; /* only used for stats */ if (read(fd, buf, blocksz) != blocksz) { perror("read failed"); exit(1); } } else { offset = (off_t) (random() % (numblocks - 1)) * blocksz; if (lseek(fd, offset, SEEK_SET) == -1) { perror("seek failed"); exit(1); } if (read(fd, buf, blocksz) != blocksz) { perror("read failed"); exit(1); } } /* If we are collecting stats...*/ if (stats){ if (i == 0) { offsetmin = offsetmax = offset; offsetsum = (double)offset; offsetsumx2 = (double)offset*(double)offset; } else { if (offset < offsetmin) offsetmin = offset; if(offset > offsetmax) offsetmax = offset; offsetsum += (double)offset; offsetsumx2 += (double)offset*(double)offset; } } } free(buf); /* Close file now we are finished. */ close(fd); gettimeofday(&endtp, NULL); timersub(&endtp, &starttp, &elapsedtp); elapsed = (double)elapsedtp.tv_sec + (double)elapsedtp.tv_usec/1000000.0; iorate = (double)((double)numblocks*(double)blocksz)/(double)elapsed; printf("%s reads: %d of: %d bytes elapsed: %.4fs io rate: %.0f bytes/s\n", (seq == 1) ? "sequential" : "random", numblocks, blocksz,elapsed, iorate); if (stats) { printf("max offset: %d min offset: %d\n", offsetmax, offsetmin); printf("avg offset: %.0f ", offsetsum / (double)numblocks); printf("stddev offset: %.0f\n", sqrt(offsetsumx2 / (double)numblocks - (offsetsum / (double)numblocks) * (offsetsum / (double)numblocks))); } free(file); exit(0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?45921C76.8020200>