Previous | Table of Contents | Next |
If you want to see these examples in action, run two copies of the Performance Monitor, and load LogicalDisk.PMW into one copy and PhysicalDisk.PMW into the other. Then, run the DiskHog.EXE program. The source code for DiskHog is shown in Listing 6.4.
Listing 6.4 The DiskHog example application source code.
//------------------------------------------------------------------------------------ // THIS CODE AND INFORMATION IS PROVIDED AS IS WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // // DiskHog.C Sample Application to demonstrate // I/O intensive application. // // // Copyright (c) 1993-1997 Knowles Consulting. All rights Reserved. // //------------------------------------------------------------------------------------ #include <windows.h> #include <stdlib.h> #include <stdio.h> #define MAX_MEM_SIZE 1048576 #define FILE_NAME \\DumpFile.DAT int main (int argc, char *argv[]) { HGLOBAL ptrMemBlock; FILE *fFileHandle; int i,x,z; char chChar; char szFileName[MAX_PATH]; // Clear file name variable. memset(szFileName, '\n', MAX_PATH); if (argc > 1) { // Copies disk drive command-line argument and adds file name. strcpy(szFileName, argv[1]); strcat(szFileName, FILE_NAME); } else { // If no drive specified, use C:. strcpy(szFileName, C: ); strcat(szFileName, FILE_NAME); } // Try finally block. __try { z=0; // Allocate a 1MB block of memory. ptrMemBlock = GlobalAlloc(GPTR, MAX_MEM_SIZE); if (ptrMemBlock != NULL) { // Set block of memory to all '*'. memset(ptrMemBlock, '*', MAX_MEM_SIZE); // Open file. fFileHandle = fopen(szFileName,"w+" ); if (fFileHandle != NULL) { // Copies 1MB block of data to file 1,000 times. for (i=0;i<1000;i++) { x = fwrite(ptrMemBlock, MAX_MEM_SIZE, 1, fFileHandle); (x < 1) { break; } else { z+=x; } } } } } // When completed or interrupted, display message, delete file, // and wait for user to press any key. __finally { printf("Created a file of %d bytes!\r\n" , (z * MAX_MEM_SIZE)); printf("Press any key to continue!\r\n" ); chChar=getchar(); // Free allocated memory. if (ptrMemBlock != NULL) { GlobalFree(ptrMemBlock); } // Close, then delete file. if (fFileHandle != NULL) { fclose(fFileHandle); remove(szFileName); } } return (FALSE); }
This program takes one command-line argumentthe drive letter to write its data file to (for example, DiskHog H:). The default if no drive letter is specified is the C: drive. This program will write up to 1,000 1MB blocks of data to the file (DumpFile.DAT) or a 1GB file. The purpose of this program is twofold. First, it can be used to demonstrate disk activity on logical drives, as shown in Figure 6.9, and disk activity on physical drives, as shown in Figure 6.10. Secondly, it can be used to test your alert conditions for low disk space. When the program has finished writing the data file, it will inform you of how much data was written and prompt you to press a key to continue. At this point, it will delete the data file it created.
Figure 6.9 An example of a disk-intensive application displayed with Performance Monitor on logical drives.
Figure 6.10 An example of a disk-intensive application displayed with Performance Monitor on physical drives.
Keep in mind that DiskHog.EXE is a simulation designed to overload your disk I/O subsystem. As such, it cannot be used to demonstrate a normal usage pattern for a file server. It is only designed to give you an idea of what to look for in finding performance bottlenecks with the Performance Monitor.
WARNING: If you run this program and place the data file on a compressed drive, it will most likely run to completion and write almost a gigabyte of data, consuming an inordinate amount of your time watching it perform its task. This will occur even if you have less than a couple hundred MB free on the drive. This is because the data block it writes is composed of 1MB of asterisks (*) and is easily compressible.
TIP: When using Performance Monitor to determine disk activities, you might want to change the default capture rate. I break mine down into 5 seconds, 1 second, 1/10 of a second, and 1/100 of a second intervals depending on the amount of data I want to capture and the server activity.
If you find a bottleneck, there are a couple options for you to implement aside from those mentioned in the beginning of this section:
If your budget is limited, spend your money on a fast SCSI controller and average disk drives (in terms of seek time) because the SCSI controller has more of an impact on a two-drive system.
On the other hand, if you have sufficient funds, purchase drives with the lowest seek time because the time seeking tracks (to find the data) versus data transfer time is on the order of 10 to 1 or higher.
Distribute the workload (one reason to use the LogicalDisk.PMW example) to place highly accessed data files on different drives. For example, you can place the application files for Microsoft Office on your first physical drive and your SQL Server databases on your second physical drive. Do not place them on different logical drives on the same physical drive because this will defeat the purpose of distributing the load.
If you use a FAT file system, defragment it occasionally. This will prevent the multiple seeks required to read or write data to the disk.
Previous | Table of Contents | Next |