[comp.benchmarks] IOstone random file I/O benchmark

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