home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / UTILS2 / PDB001.ZIP / PDB.C next >
C/C++ Source or Header  |  1994-03-09  |  8KB  |  224 lines

  1. /*----------------------------------------------------------------------*
  2.  | Portable Disk Benchmark                                              |
  3.  |                                                                      |
  4.  | Written by Albert J. Shan.                                           |
  5.  |   CompuServe: 70730,401                                              |
  6.  |   Internet:   70730.401@compuserve.com                               |
  7.  |                                                                      |
  8.  | A portable C benchmark program for testing disk cache and file       |
  9.  | I/O efficiency.                                                      |
  10.  |                                                                      |
  11.  | Version 0.01  03/09/94                                               |
  12.  | - Initial release.  Currently, it is limited to 127 512-byte blocks  |
  13.  |   (65024 bytes) due to the requirement of 16-bit operating systems   |
  14.  |   such as DOS and OS/2 1.x.  These OSes do not provide a file system |
  15.  |   call to perform write to the disk with >= 64K bytes.  The C        |
  16.  |   compiler must support timeb data structures in order to provide    |
  17.  |   reasonably accurate result.  If you're recompiling with a 16-bit   |
  18.  |   compiler, make sure you invoke the Large Memory Model.  It should  |
  19.  |   be compiled with the most aggressive optimization switches.        |
  20.  *----------------------------------------------------------------------*/
  21.  
  22. typedef  unsigned long ULONG;
  23. #include <io.h>
  24. #include <fcntl.h>
  25. #include <sys\timeb.h>
  26. #include <sys\types.h>
  27. #include <sys\stat.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <malloc.h>
  32.  
  33.  
  34. /* ANSI Standard pseudo-random number generator.
  35.    For eliminating C Library random number generator dependency. */
  36.  
  37. static unsigned long int next = 1;
  38.  
  39. int pdb_rand (void)
  40. {
  41.   next = next * 1103515245L + 12345L;
  42.   return ((int) (next / 0x10000L) & 0x7FFF);
  43. }
  44.  
  45. void pdb_srand (unsigned int seed)
  46. {
  47.   next = seed;
  48. }
  49.  
  50.  
  51.  
  52. /*----------------------------*
  53.  | Calculate time difference. |
  54.  *----------------------------*/
  55.  
  56. long DiffTime (struct timeb tStop, struct timeb tStart)
  57. {
  58.   return ((tStop.time - tStart.time) * 1000L + (long)((long)tStop.millitm - (long)tStart.millitm));
  59. }
  60.  
  61.  
  62.  
  63. /*--------------------------------------------------------------*
  64.  | 6-pass Disk Benchmark routine.                               |
  65.  |   1. Sequential Write                                        |
  66.  |   2. Random Read                                             |
  67.  |   3. Random Write (same data)                                |
  68.  |   4  Sequential Read                                         |
  69.  |   5. Random Read                                             |
  70.  |   6. Random Write (changed data)                             |
  71.  |                                                              |
  72.  | Only unbuffered file I/O calls are used to avoid compiler    |
  73.  | efficiency in buffered I/O calls.  It is all up to the file  |
  74.  | system to provide the caching.                               |
  75.  *--------------------------------------------------------------*/
  76.  
  77. int DiskBench (long FileSize, long BlockSize)
  78. {
  79.   long BlkLoc, tTotal;
  80.   int  hFile, i, Limit, NumRW;
  81.   long tWrite, tRead, tRandomWrite, tRandomRead;
  82.   long tRandomWrite2, tRandomRead2;
  83.   struct timeb tStart, tStop;
  84.   char *buf;
  85.  
  86.   buf = malloc ((unsigned int)BlockSize);
  87.   Limit = (int)(FileSize * 1024L * 1024L / BlockSize);
  88.  
  89.   /* Limit randow read/write to 1MB data regardless of BlockSize */
  90.   NumRW = (int)(1024L * 1024L / BlockSize);
  91.  
  92.   /* File create */
  93.   hFile = open ("PDBTEST.$$$", O_CREAT | O_RDWR | O_BINARY, S_IREAD | S_IWRITE);
  94.   if (hFile == -1)
  95.   {
  96.     printf ("Can't open file\n");
  97.     return (1);
  98.   }
  99.  
  100.   /* Initialize buffer block */
  101.   memset (buf, 'A', (unsigned int)BlockSize);
  102.  
  103.   /* Sequential write */
  104.   ftime (&tStart);
  105.   for (i = 0; i < Limit; i++)
  106.     write (hFile, buf, (unsigned int)BlockSize);
  107.   ftime (&tStop);
  108.   tWrite = DiffTime (tStop, tStart);
  109.   printf ("Sequential write: %3ld.%02ld secs\n", tWrite / 1000, (tWrite % 1000) / 10);
  110.  
  111.   pdb_srand (12345);
  112.  
  113.   /* Random read */
  114.   lseek (hFile, 0L, SEEK_SET);
  115.   ftime (&tStart);
  116.   for (i = 0; i < NumRW; i++)
  117.   {
  118.     BlkLoc = (long)(pdb_rand () % Limit) * BlockSize;
  119.     lseek (hFile, BlkLoc, SEEK_SET);
  120.     read (hFile, buf, (unsigned int)BlockSize);
  121.   }
  122.   ftime (&tStop);
  123.   tRandomRead = DiffTime (tStop, tStart);
  124.   printf ("     Random read: %3ld.%02ld secs\n", tRandomRead / 1000, (tRandomRead % 1000) / 10);
  125.  
  126.   pdb_srand (54321U);
  127.  
  128.   /* Random write with SAME data */
  129.   lseek (hFile, 0L, SEEK_SET);
  130.   ftime (&tStart);
  131.   for (i = 0; i < NumRW; i++)
  132.   {
  133.     BlkLoc = (long)(pdb_rand () % Limit) * BlockSize;
  134.     lseek (hFile, BlkLoc, SEEK_SET);
  135.     write (hFile, buf, (unsigned int)BlockSize);
  136.   }
  137.   ftime (&tStop);
  138.   tRandomWrite = DiffTime (tStop, tStart);
  139.   printf ("    Random write: %3ld.%02ld secs\n", tRandomWrite / 1000, (tRandomWrite % 1000) / 10);
  140.  
  141.   /* Sequential read */
  142.   lseek (hFile, 0L, SEEK_SET);
  143.   ftime (&tStart);
  144.   for (i = 0; i < Limit; i++)
  145.     read (hFile, buf, (unsigned int)BlockSize);
  146.   ftime (&tStop);
  147.   tRead = DiffTime (tStop, tStart);
  148.   printf (" Sequential read: %3ld.%02ld secs\n", tRead / 1000, (tRead % 1000) / 10);
  149.  
  150.   pdb_srand (12345);
  151.  
  152.   /* Random read pass 2 with same random seed */
  153.   lseek (hFile, 0L, SEEK_SET);
  154.   ftime (&tStart);
  155.   for (i = 0; i < NumRW; i++)
  156.   {
  157.     BlkLoc = (long)(pdb_rand () % Limit) * BlockSize;
  158.     lseek (hFile, BlkLoc, SEEK_SET);
  159.     read (hFile, buf, (unsigned int)BlockSize);
  160.   }
  161.   ftime (&tStop);
  162.   tRandomRead2 = DiffTime (tStop, tStart);
  163.   printf ("     Random read: %3ld.%02ld secs\n", tRandomRead2 / 1000, (tRandomRead2 % 1000) / 10);
  164.  
  165.   pdb_srand (54321U);
  166.  
  167.   /* Random write pass 2 with changed data */
  168.   memset (buf, 'B', (unsigned int)BlockSize);
  169.   lseek (hFile, 0L, SEEK_SET);
  170.   ftime (&tStart);
  171.   for (i = 0; i < NumRW; i++)
  172.   {
  173.     BlkLoc = (long)(pdb_rand () % Limit) * BlockSize;
  174.     lseek (hFile, BlkLoc, SEEK_SET);
  175.     write (hFile, buf, (unsigned int)BlockSize);
  176.   }
  177.   ftime (&tStop);
  178.   tRandomWrite2 = DiffTime (tStop, tStart);
  179.   printf ("    Random write: %3ld.%02ld secs\n", tRandomWrite2 / 1000, (tRandomWrite2 % 1000) / 10);
  180.  
  181.   tTotal = (long)tWrite + (long)tRead + (long)tRandomWrite +
  182.            (long)tRandomRead + (long)tRandomRead2 + (long)tRandomWrite2;
  183.   printf ("           Total: %3ld.%02ld secs\n", tTotal / 1000L, (tTotal % 1000L) / 10);
  184.  
  185.   close (hFile);
  186.   unlink ("PDBTEST.$$$");
  187.   free (buf);
  188.  
  189.   return (0);
  190. }
  191.  
  192.  
  193.  
  194. /*---------------*
  195.  | Main program. |
  196.  *---------------*/
  197.  
  198. int main (int argc, char *argv[])
  199. {
  200.   long FileSize, BlockSize;
  201.  
  202.   if (argc != 3)
  203.   {
  204.     printf ("\nPortable Disk Benchmark  V0.01  03/09/94\n\n");
  205.     printf ("usage: PDB [File size] [Blocks]\n");
  206.     printf ("  File size - File size in MB.  Allowable range: 1 to 32MB.\n");
  207.     printf ("  Blocks    - Number of blocks to read/write per I/O call.\n");
  208.     printf ("              Each block is 512 bytes.  Allowable range: 1 to 127.\n\n");
  209.     printf ("example: pdb 2 4\n");
  210.     return (1);
  211.   }
  212.  
  213.   FileSize = max (1L, atoi (argv[1]));
  214.   FileSize = min (32L, FileSize);
  215.   BlockSize = max (1L, atol (argv[2]));
  216.   BlockSize = min (127L, BlockSize);
  217.   BlockSize *= 512L;
  218.  
  219.   printf ("File size: %2ld MB  Block size: %5ld bytes\n", FileSize, BlockSize);
  220.  
  221.   return (DiskBench (FileSize, BlockSize));
  222. }
  223.  
  224.