Win32内存映射文件的性能与CRT Fopen/Fread的性能
-
09-10-2019 - |
题
我需要依次读取(扫描)文件并处理其内容。文件大小可以是从很小的(一些KB)到非常大的任何东西(一些GB)。
我在Windows 7 64位上使用VC10/VS2010尝试了两种技术:
- Win32内存映射的文件(即CreateFile,CreateFileMapping,MapViewOffile等)
- CRT的Fopen和Fread。
我认为内存映射的文件技术可能比CRT功能更快,但是一些测试表明,在两种情况下,速度几乎相同。
以下C ++语句用于MMF:
HANDLE hFile = CreateFile(
filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
HANDLE hFileMapping = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL
);
该文件是依次读取的,由块片段读取;每个块是 SYSTEM_INFO.dwAllocationGranularity
在尺寸方面。
考虑到MMF和CRT的速度几乎相同,我会使用CRT功能,因为它们更简单和多平台。但是我很好奇:我是否正确使用MMF技术?在这种情况下,MMF性能顺序与CRT ONE相同吗?
谢谢。
解决方案
我相信,如果您依次访问文件,您将不会看到太大的区别。由于文件I/O的缓存非常大,因此可能还使用了 +读取。
如果您在文件数据处理过程中有很多“跳跃”,情况会有所不同。然后,每次设置一个新的文件指针和读取新文件部分可能会杀死CRT,而MMF将为您提供最大可能的性能
其他提示
由于您依次扫描文件,因此对于任何一种方法,我都不会认为磁盘使用模式会大不相同。
对于大文件,MMF可能会降低数据局部性,甚至会导致将所有或部分放置在页面文件中的文件的副本,而通过CRT处理小型缓冲区将在RAM中通过CRT进行处理。在这种情况下,MMF可能会更慢。您可以一次仅在一部分基础文件中映射来缓解此问题,但是随后情况变得更加复杂,而无需赢得直接顺序I/O的任何胜利。
MMF实际上是Windows实施过程间共享内存的方式,而不是一种加快广义文件I/O的方式。内核中的文件管理器缓存是您真正需要在此处利用的内容。
我认为内存映射的文件技术可能比CRT功能更快,但是一些测试表明,在两种情况下,速度几乎相同。
您可能正在击中文件系统缓存以进行测试。除非您明确创建文件处理以绕过文件系统缓存(FILE_FLAG_NO_BUFFERING
打电话时 CreateFile
),文件系统缓存将启动并将最近访问的文件保存在内存中。
在读取文件系统缓存中使用缓冲的文件中,由于操作系统必须执行额外的副本以及系统调用开销,因此有很小的速度差异。但是出于您的目的,您可能应该坚持使用CRT文件功能。
古斯塔沃·杜阿尔特(Gustavo Duarte)有一篇关于内存映射文件的精彩文章 (从通用OS的角度来看)。
两种方法最终都会归结为磁盘I/O,这将是您的瓶颈。我会使用一种方法,即我的较高级别功能更喜欢 - 如果我需要流式传输,我将使用文件,如果我需要顺序访问和固定大小的文件,我会考虑内存映射的文件。
或者,如果您的算法仅在内存上起作用,则MEM映射文件可能会更容易出去。