我需要依次读取(扫描)文件并处理其内容。文件大小可以是从很小的(一些KB)到非常大的任何东西(一些GB)。

我在Windows 7 64位上使用VC10/VS2010尝试了两种技术:

  1. Win32内存映射的文件(即CreateFile,CreateFileMapping,MapViewOffile等)
  2. 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映射文件可能会更容易出去。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top