home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume17 / iozone / part01 / iozone.c
Encoding:
C/C++ Source or Header  |  1991-03-23  |  7.5 KB  |  264 lines

  1. /*
  2. *    "IO Zone" Benchmark Program
  3. *
  4. *    Author:    Bill Norcott (Bill.Norcott@nuo.mts.dec.com)
  5. *        4 Dunlap Drive
  6. *        Nashua, NH  03060
  7. *
  8. *  "Copyright 1991,   William D. Norcott
  9. *  This is free software.  License to freely use and distribute this
  10. *  software is hereby granted by the author, subject to the condition
  11. *  that this copyright notice remains intact."
  12. *
  13. * "This test writes a 4 MEGABYTE sequential file in 512 byte chunks, then
  14. * rewinds it  and reads it back.  [The size of the file should be
  15. * big enough to factor out the effect of any disk cache.]
  16. *       
  17. * The file is written (filling any cache buffers), and then read.  If the
  18. * cache is >= 4 MB, then most if not all the reads will be satisfied from
  19. * the cache.  However, if it is less than or equal to 2 MB, then NONE of
  20. * the reads will be satisfied from the cache.  This is becase after the 
  21. * file is written, a 2 MB cache will contain the upper 2 MB of the test
  22. * file, but we will start reading from the beginning of the file (data
  23. * which is no longer in the cache)
  24. * In order for this to be a fair test, the length of the test file must
  25. * be AT LEAST 2X the amount of disk cache memory for your system.  If
  26. * not, you are really testing the speed at which your CPU can read blocks
  27. * out of the cache (not a fair test)
  28. *       
  29. * IOZONE does NOT test the raw I/O speed of your disk or system.  It
  30. * tests the speed of sequential I/O to actual files.  Therefore, this
  31. * measurement factors in the efficiency of you machines file system,
  32. * operating system, C compiler, and C runtime library.  It produces a 
  33. * measurement which is the number of bytes per second that your system
  34. * can read or write to a file.  For UNIX systems I call fsync() to force
  35. * the writes to disk.  This gives a test of the time it takes to
  36. * actually get data onto the disk.
  37. *       
  38. * This program has been ported and tested on the following computer
  39. * operating systems:
  40. *    VAX/VMS V5.4, Ultrix V4.1, OSF/1 and MS-DOS 3.3"
  41. *       
  42. * --- MODIFICATION HISTORY:
  43. *
  44. *   3/7/91 William D. Norcott (Bill.Norcott@nuo.mts.dec.com)
  45. *        created
  46. *   3/22/91 Bill Norcott    tested on OSF/1 ... it works
  47. *
  48. */
  49. #ifdef    __MSDOS__        /* Turbo C define this way for PCs... */
  50. #define    MSDOS            /* Microsoft C defines this */
  51. #endif
  52. /* VMS and MS-DOS both have ANSI C compilers and use rand()/srand() */
  53. #ifdef    VMS_POSIX
  54. #undef   VMS
  55. #define    ANSI_RANDOM    1
  56. #endif
  57. #ifdef    MSDOS
  58. #define    ANSI_RANDOM    1
  59. #endif
  60.  
  61. #if defined(VMS)
  62. #define    ANSI_RANDOM    1
  63. #include    <math.h>
  64. #include    <unixio.h>
  65. #include    <ssdef.h>
  66. #include    <file.h>
  67.  
  68. #elif defined(MSDOS)
  69. #include <fcntl.h>
  70. #elif defined(unix)
  71. #include <sys/file.h>
  72. #include <limits.h>
  73. #endif
  74.  
  75. #define MEGABYTES 1            /* number of megabytes in file */
  76. #define RECLEN 512            /* number of bytes in a record */
  77. #define FILESIZE (MEGABYTES*1024*1024)    /*size of file in bytes*/
  78. #define NUMRECS FILESIZE/RECLEN        /* number of records */
  79. #define MAXBUFFERSIZE 16*1024        /*maximum buffer size*/
  80. #define TOOFAST 10
  81. #define USAGE  "\tUsage:\tiozone [megabytes] [record_length] [[path]filename]\n\n"
  82. #define THISVERSION "V1.01"
  83.  
  84. /* Define only one of the following two.*/
  85. /*#define NOTIME        define if no time function in library*/
  86. #define TIME                /*Use time(2)function*/
  87.  
  88. #define MAXNAMESIZE 1000                /* max # of characters in filename */
  89.  
  90. main(argc,argv) 
  91.       int argc;
  92.      char *argv[];
  93. {
  94. int fd;
  95. char filename [MAXNAMESIZE];            /* name of temporary file */
  96. #ifdef    VMS
  97. char *default_filename="iozone_temp_file"; /*default name of temporary file*/
  98. #else
  99. #ifdef    MSDOS
  100. char *default_filename="iozone.tmp"; /*default name of temporary file*/
  101. #else 
  102. char *default_filename="/tmp/iozone_temp_file"; /*default name of temporary file*/
  103. #endif
  104. #endif 
  105. #ifdef    MSDOS
  106. char *buffer; 
  107. #else
  108. char buffer [MAXBUFFERSIZE];        /*a temporary data buffer*/
  109. #endif
  110. int i, status;
  111. unsigned long megabytes = MEGABYTES, goodmegs;
  112. unsigned long reclen = RECLEN, goodrecl;
  113. unsigned long filesize = FILESIZE;
  114. unsigned long numrecs = NUMRECS;
  115.  
  116. #ifdef TIME
  117.  long time();
  118.  long starttime1, starttime2;
  119.  long writetime;
  120.  long totaltime;
  121.  
  122. #endif
  123.  
  124. #ifdef MSDOS
  125.   buffer = (char *) malloc(MAXBUFFERSIZE);
  126. #endif
  127.  
  128.   printf("\n\tIOZONE: Performance Test of Sequential File I/O  --  %s\n",
  129.           THISVERSION);
  130.   printf("\t\tBy Bill Norcott\n\n");
  131.  
  132.   strcpy(filename,default_filename);
  133.   switch (argc) {
  134.     case 1:       /* no args, take all defaults */
  135.       printf(USAGE);
  136.     break;
  137.     case 2:     /* <megabytes|filename> */
  138.     i = atoi(argv[1]); if (i) {
  139.       megabytes = i;
  140.     } else {
  141.       strcpy(filename,argv[1]);
  142.         }
  143.     break;
  144.     case 3:     /* <megabytes> <reclen|filename> */
  145.     filesize = atoi(argv[1]);
  146.     i = atoi(argv[2]); if(i) {
  147.       reclen = (unsigned) i;
  148.     } else {
  149.       strcpy(filename,argv[2]);
  150.     }
  151.     break;
  152.     case 4:     /* <megabytes> <reclen> <filename> */
  153.     filesize = atoi(argv[1]);
  154.     reclen = atoi(argv[2]);
  155.     strcpy(filename,argv[3]);
  156.     break;
  157.     default:
  158.       printf(USAGE);
  159.       exit(1);
  160.  
  161.   }
  162.   printf("\tSend comments to:\tBill.Norcott@nuo.mts.dec.com\n\n");
  163.  
  164.   filesize = megabytes*1024*1024;
  165.   numrecs = filesize/reclen;
  166.   if (reclen >  MAXBUFFERSIZE) {
  167.     printf("Error: Maximum record length is %d bytes\n", MAXBUFFERSIZE);
  168.     }
  169.   printf("\tIOZONE writes a %ld Megabyte sequential file consisting of\n",
  170.     megabytes);
  171.   printf("\t%ld records which are each %ld bytes in length.\n",
  172.     numrecs, reclen);
  173.   printf("\tIt then reads the file.  It prints the bytes-per-second\n");
  174.   printf("\trate at which the computer can read and write files.\n\n");
  175.   printf("\nWriting the %ld Megabyte file, '%s'...", megabytes, filename);
  176.  
  177. #ifdef TIME
  178.     starttime1 = time(0);
  179. #endif
  180.     if((fd = creat(filename, 0640))<0){
  181.         printf("Cannot create temporary file\n");
  182.         exit(1);
  183.     }
  184.     for(i=0; i<numrecs; i++){
  185.         write(fd, buffer, (unsigned) reclen);
  186.     }
  187.  
  188. #ifdef TIME
  189.     writetime = time(0) - starttime1;
  190.     printf("%d seconds", writetime);
  191. #endif
  192.     close(fd);
  193. #ifdef VMS
  194.     if((fd = open(filename, O_RDONLY, 0640))<0){
  195.         printf("Cannot open temporary file for read\n");
  196.         exit(1);
  197. #elif defined(MSDOS)
  198.     if((fd = open(filename, O_RDONLY, 0640))<0){
  199.         printf("Cannot open temporary file for read\n");
  200.         exit(1);
  201. #else
  202.     if((fd = open(filename, O_RDONLY))<0){
  203.         printf("Cannot open temporary file for read\n");
  204.         exit(1);
  205. #endif
  206.     }
  207.  
  208.             /*start timing*/
  209. #ifdef NOTIME
  210.     printf("start timing\n");
  211. #endif
  212.  
  213.     printf("\nReading the file...");
  214.     starttime2 = time(0);
  215.    for(i=0; i<numrecs; i++) {
  216.     if(read(fd, buffer, (unsigned) reclen) < 0)
  217.         perror("Read error");
  218.     }
  219. #ifdef NOTIME
  220.     printf("stop timing\n");
  221. #endif
  222. #ifdef TIME
  223.     totaltime = time(0) - starttime2;
  224.  
  225.     printf("%d seconds\n", totaltime);
  226.     if(totaltime!=0)
  227.     {   
  228.         printf("\nIOZONE performance measurements:\n");
  229.         printf("\t%ld bytes/second for writing the file\n",
  230.          (long) ((numrecs*reclen)/writetime) );
  231.         printf("\t%ld bytes/second for reading the file\n",
  232.         (long) ((numrecs*reclen)/totaltime) );
  233.         if (totaltime < TOOFAST) {
  234.         goodmegs = (TOOFAST/totaltime)*2*megabytes;
  235.         printf("\nThis machine is fast (or is using a disk cache)!\n");
  236.         printf("You will get a more accurate measure of its\n");
  237.         printf("performance by re-running IOZONE using the command:\n");
  238.         printf("\n\tiozone %d ", goodmegs);
  239.         printf("\t(i.e., file size = %d megabytes)\n", goodmegs);
  240.         }
  241.     } else {
  242.         goodrecl = reclen/2;
  243.         printf("\nI/O error during read.  Try again with the command:\n");
  244.         printf("\n\tiozone %d %d ",megabytes, (int) goodrecl);
  245.         printf("\t(i.e. record size = %d bytes)\n", (int) goodrecl);
  246.     }
  247. #endif
  248.     close(fd);
  249. #ifndef VMS
  250.     unlink(filename);    /* delete the file */
  251.                     /*stop timer*/
  252. #endif
  253. #ifdef    MSDOS
  254.     free(buffer);        /* deallocate the memory */
  255. #endif
  256. #ifdef VMS
  257. return SS$_NORMAL;
  258. #else
  259. return 0;
  260. #endif
  261. }
  262.  
  263.  
  264.