Re: Cached file read performance



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);

}
_______________________________________________
freebsd-performance@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-performance
To unsubscribe, send any mail to "freebsd-performance-unsubscribe@xxxxxxxxxxx"



Relevant Pages