Example: Sequential File Processing with Mapped Files
The atou program (Program 2-4) illustrates sequential file processing by converting ASCII files to Unicode, doubling the file length. This is an ideal application for memory-mapped files because the most natural way to convert the data is to process it one character at a time without being concerned with file I/O. Program 5-3 simply maps the input file and the output filefirst computing the output file length by doubling the input file lengthand converts the characters one at a time.
This example clearly illustrates the trade-off between the file mapping complexity required to initialize the program and the resulting processing simplicity. This complexity may not seem worthwhile given the simplicity of a simple file I/O implementation, but there is a significant performance advantage. Appendix C shows that the memory-mapped version can be considerably faster than the file access versions for NTFS files, so the complexity is worthwhile. The book's Web site contains additional performance studies; the highlights are summarized here.
Memory-mapping performance improvements apply only to Windows NT and the NTFS. Compared with the best sequential file processing techniques, the performance improvements can be 3:1 or greater. The performance advantage disappears for larger files. In this example, as the input file size approaches about one-third of the physical memory size, normal sequential scanning is preferable. The mapping performance degrades at this point since the input file fills one-third of the memory and the output file, which is twice as long, fills the other two-thirds, forcing parts of the output files to be flushed to disk. Thus, on a 192MB system, mapping performance degenerates for input files longer than 60MB. Most file processing deals with smaller files and can take advantage of file mapping.
Program 5-3 shows only the function Asc2UnMM. The main program is the same as for Program 2-4.
Program 5-3. Asc2UnMM: File Conversion with Memory Mapping
/* Chapter 5. Asc2UnMM.c: Memory-mapped implementation. */
#include "EvryThng.h" BOOL Asc2Un (LPCTSTR fIn, LPCTSTR fOut, BOOL bFailIfExists) { HANDLE hIn, hOut, hInMap, hOutMap; LPSTR pIn, pInFile; LPWSTR pOut, pOutFile; DWORD FsLow, dwOut;
/* Open and map both the input and output files. */ hIn = CreateFile (fIn, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); hInMap = CreateFileMapping (hIn, NULL, PAGE_READONLY, 0, 0, NULL); pInFile = MapViewOfFile (hInMap, FILE_MAP_READ, 0, 0, 0);
dwOut = bFailIfExists ? CREATE_NEW : CREATE_ALWAYS; hOut = CreateFile (fOut, GENERIC_READ | GENERIC_WRITE, 0, NULL, dwOut, FILE_ATTRIBUTE_NORMAL, NULL); FsLow = GetFileSize (hIn, NULL); /* Set the map size. */ hOutMap = CreateFileMapping (hOut, NULL, PAGE_READWRITE, 0, 2 * FsLow, NULL); pOutFile = MapViewOfFile (hOutMap, FILE_MAP_WRITE, 0, 0, (SIZE_T)(2 * FsLow));
/* Convert the mapped file data from ASCII to Unicode. */ pIn = pInFile; pOut = pOutFile; while (pIn < pInFile + FsLow) { *pOut = (WCHAR) *pIn; pIn++; pOut++; }
UnmapViewOfFile (pOutFile); UnmapViewOfFile (pInFile); CloseHandle (hOutMap); CloseHandle (hInMap); CloseHandle (hIn); CloseHandle (hOut); return TRUE; }
|
No comments:
Post a Comment