Skip site navigation (1)Skip section navigation (2)
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>