norcott@databs.enet.dec.com (Bill Norcott) (03/27/91)
Attached is my PORTABLE version of Alvin Park's IOstone benchmark of random acccess file I/O. I have ported it from the original Unix to both VMS and MS-DOS. This code will compile and run on all these operating systems. I have also added in comments some statistics I have gathered for the IOstone test. This test is influenced by the size of the buffer cache, processor speed, and efficiency of the C compiler. However, together with my own IOzone benchmark (posted earlier), it will give an estimate of system performance. I would be interested on any comment on the port or benchmark results. Regards, Bill Norcott Digital Equipment Corporation ----------------------- CUT HERE ----------------------------------- /* * "I/O Stone" Benchmark Program * * Written by: Arvin Park (park@princeton) * Department of Computer Science * Princeton University * Princeton, New Jersey 08544 * (609) 452-6304 [--enm: no longer this phone or address] * * Ported to MS-DOS and VAX/VMS by William D. Norcott * Digital Equipment Corporation * Bill.Norcott.nuo.mts.dec.com * "I appreciate your comments and benchmark results" Bill Norcott * * Version: C/1 * Date: 12/10/86 * * Defines: If your version of "C" does not include a time(2) * function, define NOTIME. Use a stopwatch to measure * elapsed wall time. Divide 400000 by the elapsed time * to get the correct number of iostones/second. * * To compile: cc -O io.c -o io * * Note: [1] This program should be run without other processes * competing for system resources. Run it in the dead of * night if you have to. * * [2] This program uses 4 megabytes of disk space. Make * sure that at least this much space is available on * your file system before you run the program. * * Results: If you get results from a new (machine/operating * system/disk controller and drive) combination please * send them to park@princeton. Please include complete * ********* no! send them to eugene@ames-aurora.arpa***** * ********* do not bother Arvin as he is no longer @princeton * information on the machine type, operating system, * version, disk controller, and disk drives. Also make * a note of any system modifications that have been * performed. * --- Berkeley results: * Results from Gary Casterline at Berkeley, Bill Norcott at Digital, * Vasu Subramanian at Digital * * machine iostone/s stddev configuration (comment) * ---------- --------- ---------- ------------------------------------- * 20 MHz 386 1769 n/a MS-DOS 3.3, Rodime 3259T 210MB (SCSI) * Adaptec 1542B SCSI controller (16-bit) * 4 MB, 80 nsec main memory, no CPU cache * 480 K writethrouh disk cache * my 80386 PC., W. Norcott 3/11/91 * 20 MHz 386 1709 n/a MS-DOS 3.3, CDC Imprimis 94161-155 (SCSI) * Adaptec 1542B SCSI controller (16-bit) * 4 MB, 80 nsec main memory, no CPU cache * 480 K writethrouh disk cache * my 80386 PC., W. Norcott 2/25/91 * 20 MHZ 386 1606 n/a MS-DOS 3.3, Seagate ST-296N (SCSI), * Seagate ST-01 SCSI controller (8-bit) * 4 MB, 80 nsec main memory, no CPU cache * 480K write through disk cache, 29% hit rate * my 80386 PC, W. Norcott 3/22/90 * 20 MHz 386 1526 n/a MS-DOS 3.3, Rodime 3259T 210 MB (SCSI) * Adaptec 1542B SCSI controller (16-bit) * 4 MB, 80 nsec main memory, no CPU cache * NO disk cache * my 80386 PC., W. Norcott 2/25/91 * 20 MHz 386 1311 n/a MS-DOS 3.3, CDC Imprimis 94161-155 (SCSI) * Adaptec 1542B SCSI controller (16-bit) * 4 MB, 80 nsec main memory, no CPU cache * NO disk cache * my 80386 PC., W. Norcott 2/25/91 * 20 MHz 386 1204 n/a MS-DOS 3.3, Seagate ST296N (SCSI) * Adaptec 1542B SCSI controller (16-bit) * 4 MB, 80 nsec main memory, no CPU cache * NO disk cache * my 80386 PC., W. Norcott 2/25/91 * VAX 3500 1120 n/a VMS V5.3, VAX C 3.0, RA70, RQDX3, Q-bus, * NO CACHE, synch I/O, W. Norcott 3/21/90 * VAX 3500 1892 n/a VMS V5.3, VAX C 3.0, RA82, KDA50, Q-bus, * NO CACHE, synch I/O, W. Norcott 3/22/90 * VAX 3500 80,000 n/a VMS V5.3, VAX C 3.0, RA70, RQDX3, Q-bus, * NO CACHE, asynch I/O, W. Norcott 3/21/90 * VAX 8800 200,000 n/a VMS V5.3, VAX C 3.0, RA90, HSC70, VAXBI bus, * NO CACHE, asynch I/O, W. Norcott 3/22/90 * DS3100 4651 n/a RZ55/24M/ULTRIX V4.0 * DS5000 11764 n/a RZ57/56M/ULTRIX V3.1D * VS2000 1568 n/a RD54/6M/ULTRIX V4.0 * VAX3500 1809 n/a RD54/16M/ULTRIX V4.0 * VAX3600 8888 n/a RA82/32M/ULTRIX V3.0 * VAX6210 30769 n/a RA81/64M/ULTRIX V4.0 * vax 11/750 1988.200 (27.408) RA81/Unibus/uda50 * dec 3100 2368.000 (158.294) scsi (ask rusty about smelt) * dec 3max 3933.600 (131.586) scsi (ask brad about yaya) * dec 5400 13086.400 (492.755) RA90/qbus/kda50 (ask brad about icw) * sun 4/330 24631.900 (2095.237) scsi (ask kyle about the loaner) * * --- iostone.c source code: * * --- MODIFICATION HISTORY: * * 2/25/91 William D. Norcott (Bill.Norcott@nuo.mts.dec.com) * ANSI-fy and try with Turbo C++ compiler * 3/21/90 William D. Norcott (norcott@vmsdev.enet.dec.com), STAR::NORCOTT * Digital Equipment Corporation, VMS Development * Port this thing to VAX/VMS V5.x using VAX C 3.x * * 3/22/90 William D. Norcott (norcott@vmsdev.enet.dec.com), STAR::NORCOTT * Digital Equipment Corporation, VMS Development * Port this thing to MS-DOS 3.3 using Borland Turbo C V1.0 * * * . 3/20/90 Alex Bronstein (Alex@decwrl.dec.com): modified to let the user * give the name of the temporary file as a command line argument. If no * name is given, default to the old hardwired name. * */ #ifdef __MSDOS__ /* Turbo C define this way for PCs... */ #define MSDOS /* Microsoft C defines this */ #endif /* VMS and MS-DOS both have ANSI C compilers and use rand()/srand() */ #ifdef VMS_POSIX #undef VMS #define ANSI_RANDOM 1 #endif #ifdef MSDOS #define ANSI_RANDOM 1 #endif #ifdef VMS #define ANSI_RANDOM 1 #endif #ifdef VMS #include <math.h> #include <unixio.h> #define VMS_ASYNC_IO "fop = cbt, dlt, tmp", \ "rop = asy", \ "mbc=32", \ "mbf=12", \ "alq=8192", \ "mrs=8192", \ "rfm=fix" #define VMS_SYNC_IO "fop = cbt, dlt, tmp", \ "mbc=32", \ "mbf=12", \ "alq=8192", \ "mrs=8192", \ "rfm=fix" #define VMS_CREAT_OPTIONS VMS_SYNC_IO #endif #define FILESIZE (4L*1024L*1024L) /*size of file in bytes*/ #ifdef MSDOS #define MAXBUFFERSIZE 65536 /*maximum buffer size*/ #else #define MAXBUFFERSIZE (64L*1024L) /*maximum buffer size*/ #endif #define NBLOCKSIZES 9 /*number of different block sizes*/ #define SEED 34710373L /*random number generator seed*/ #define CONST 100000L /*iostone normalization constant*/ #define ITER 4 /*number of iterations of the code*/ /* Define only one of the following two.*/ /*#define NOTIME /*define if no time function in library*/ #define TIME /*Use time(2)function*/ #define MAXNAMESIZE 1000 /* max # of characters in filename */ char filename [MAXNAMESIZE]; /* name of temporary file */ #ifdef VMS char *default_filename="iostone_temp_file"; /*default name of temporary file*/ #else #ifdef MSDOS char *default_filename="iostone.tmp"; /*default name of temporary file*/ #else char *default_filename="/tmp/iostone_temp_file"; /*default name of temporary file*/ #endif #endif #ifdef MSDOS char *buffer; #else char buffer [MAXBUFFERSIZE]; /*a temporary data buffer*/ #endif unsigned int nbytes; /*number of bytes transferred*/ int fd; /*file descriptor*/ long offset; /*file offset*/ int i,j,k; /*counter variables*/ long bsize [NBLOCKSIZES]; /*array for different block sizes*/ int bfreq [NBLOCKSIZES]; /*number of accesses for each block*/ #ifdef TIME long time(); long starttime1, starttime2; long writetime; long totaltime; #endif main(argc,argv) int argc; char *argv[]; { printf("IOSTONE: Disk I/O Test.\n"); printf("\tby Alvin Park\t\tMS-DOS & VMS versions by Bill Norcott 3/22/90\n"); #ifdef MSDOS buffer = (char *) malloc(MAXBUFFERSIZE); #endif if (argc > 2) { printf("usage: %s filename \nor just: %s\nto use the default temporary file: %s\n", argv[0], argv[0], default_filename); exit(1); } else if (argc == 2) { strcpy(filename,argv[1]); } else { strcpy(filename,default_filename); } printf("Now doing I/O test on: %s (Have at least 4 MB free there...)\n",filename); printf("\nWriting the 4 MB file..."); #ifdef TIME starttime1 = time(0); #endif init(); #ifdef TIME writetime = time(0) - starttime1; printf("%d seconds", writetime); #endif /*start timing*/ #ifdef NOTIME printf("start timing\n"); #endif printf("\nStarting random read tests..."); starttime2 = time(0); for(k=0; k<ITER; k++) /*perform string of file operations*/ readswrites(); /*stop timer*/ #ifdef NOTIME printf("stop timing\n"); #endif #ifdef TIME totaltime = time(0) - starttime2; printf("elapsed read time = %ld\n", totaltime); if(totaltime!=0) printf("This machine benchmarks at %ld iostones/second\n", (long) (CONST*ITER)/totaltime); #endif #ifdef MSDOS unlink(filename); /* delete the file */ free(buffer); /* deallocate the memory */ #endif return 0; } init(){ /* create a temporary file*/ #ifdef VMS if((fd = creat(filename, 0640, VMS_CREAT_OPTIONS))<0){ printf("init: Cannot create temporary file\n"); exit(1); } /*To both read and write the file*/ /*it must be closed then opened*/ #else if((fd = creat(filename, 0640))<0){ printf("init: Cannot create temporary file\n"); exit(1); } /*To both read and write the file*/ /*it must be closed then opened*/ close(fd); if((fd = open(filename,2))<0){ printf("init: Cannot open temporary file\n"); exit(1); } /*Unlink the file so that it will*/ /*disappear when the program*/ /*terminates.*/ /* for MSDOS, unlink when done */ #ifndef MSDOS unlink(filename); #endif #endif lseek(fd,0L,0); /*write initial portion of file*/ for(i=0; i<(FILESIZE)/4096; i++){ if((nbytes = write(fd, buffer, 4096))<0){ printf("init: error writing block\n"); exit(1); } } /*set file block sizes and access*/ /*frequencies.*/ bsize[0] = 256; bfreq[0] = 128; bsize[1] = 512; bfreq[1] = 64; bsize[2] = 1024; bfreq[2] = 64; bsize[3] = 2048; bfreq[3] = 64; bsize[4] = 4096; bfreq[4] = 32; bsize[5] = 8192; bfreq[5] = 16; bsize[6] = 16384; bfreq[6] = 8; bsize[7] = 32768; bfreq[7] = 4; bsize[8] = 65536; bfreq[8] = 4; #ifdef ANSI_RANDOM srand(SEED); /*initialize random number generator*/ #else random(SEED); /*initialize random number generator*/ #endif return 0; } readswrites(){ for(j=0; j<NBLOCKSIZES; j++){ for(i=0; i<bfreq[j]; i++){ #ifdef ANSI_RANDOM offset=(long) ((rand()%(FILESIZE/bsize[j]))*bsize[j]); #else offset=(long) ((random()%(FILESIZE/bsize[j]))*bsize[j]); #endif lseek(fd,offset,0); if((nbytes = read(fd, buffer, bsize[j]))<0){ printf("readwrites: read error\n"); exit(1); } #ifdef ANSI_RANDOM offset=(long) ((rand()%(FILESIZE/bsize[j]))*bsize[j]); #else offset=(long) ((random()%(FILESIZE/bsize[j]))*bsize[j]); #endif lseek(fd, offset, 0); if((nbytes = read(fd, buffer, bsize[j]))<0){ printf("readswrites: read error\n"); exit(1); } #ifdef ANSI_RANDOM offset=(long) ((rand()%(FILESIZE/bsize[j]))*bsize[j]); #else offset=(long) ((random()%(FILESIZE/bsize[j]))*bsize[j]); #endif lseek(fd, offset, 0); if((nbytes = write (fd, buffer, bsize [j]))<0){ printf("readswrites: write error\n"); exit(1); } } } return 0; }
tbray@watsol.waterloo.edu (Tim Bray) (03/27/91)
norcott@databs.enet.dec.com (Bill Norcott) writes:
Attached is my PORTABLE version of Alvin Park's IOstone benchmark of
random acccess file I/O.
* [2] This program uses 4 megabytes of disk space. Make
* sure that at least this much space is available on
* your file system before you run the program.
Don't know about MS/DOS, but on most modern Unix systems, and I'm pretty
sure on VMS too, lots of quick "seeks" in a 4-Mb file will result in
the whole file quickly migrating into the file system cache.
The results from this program are interesting and probably very useful
in predicting the performance of certain classes of application; what is
being measured is the efficiency of the filesys cache implementation;
the results are likely pretty well independent of the performance of the
underlying disk hardware.
Cheers, Tim Bray, Open Text Systems