C++ Win32内存映射文件与CRT fopen/fread的性能对比
我需要按顺序读取(扫描)文件并处理其内容。 文件大小可以是非常小(一些KB)到非常大(一些GB)的任何大小 我在Windows 7 64位上使用VC10/VS2010尝试了两种技术:C++ Win32内存映射文件与CRT fopen/fread的性能对比,c++,performance,winapi,memory-mapped-files,C++,Performance,Winapi,Memory Mapped Files,我需要按顺序读取(扫描)文件并处理其内容。 文件大小可以是非常小(一些KB)到非常大(一些GB)的任何大小 我在Windows 7 64位上使用VC10/VS2010尝试了两种技术: Win32内存映射文件(即CreateFile、CreateFileMapping、MapViewOfFile等) fopen和fread来自CRT 我认为内存映射文件技术可能比CRT函数更快,但一些测试表明,这两种情况下的速度几乎相同 以下的C++语句用于MMF: HANDLE hFile = CreateFil
以下的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\u INFO.dwAllocationGranularity
考虑到MMF和CRT的速度几乎相同,我会使用CRT函数,因为它们更简单,而且是多平台的。但我很好奇:我是否正确使用了MMF技术?在这种顺序扫描文件的情况下,MMF性能与CRT相同,这正常吗
谢谢。如果按顺序访问文件,我相信您不会看到太大的差异。由于文件I/O的缓存量很大,因此可能还使用了+预读
如果在文件数据处理过程中有许多“跳跃”,情况就会不同。然后,每次设置一个新的文件指针并读取一个新的文件部分都可能会杀死CRT,而MMF将为您提供最大可能的性能,因为您是按顺序扫描文件,所以我不希望这两种方法的磁盘使用模式有太大的不同 对于大型文件,MMF可能会减少数据的局部性,甚至会导致文件的全部或部分副本放在页面文件中,而使用小型缓冲区通过CRT进行的处理都会在RAM中进行。在这种情况下,MMF可能会更慢。您可以通过一次只映射底层文件的一部分来缓解这种情况,但这样事情就会变得更加复杂,而不可能赢得直接顺序I/O
MMF实际上是Windows实现进程间共享内存的方式,而不是加速通用文件I/O的方式。内核中的文件管理器缓存是您真正需要利用的。这两种方法最终都会涉及磁盘I/O,这将是您的瓶颈。我会用一种方法,我的更高层次的功能更喜欢-如果我需要流,我将与文件,如果我需要顺序访问和固定大小的文件,我会考虑内存映射文件。 或者,如果您有一个只在内存上工作的算法,那么mem映射文件可能更容易解决 我以为那个内存映射文件 这项技术可能比CRT快 功能,但一些测试表明 两者的速度几乎相同 案例 您可能正在访问文件系统缓存进行测试。除非显式创建文件句柄以绕过文件系统缓存(
file\u FLAG\u NO\u BUFFERING
调用CreateFile
),否则文件系统缓存将启动并将最近访问的文件保留在内存中
在打开缓冲的情况下读取文件系统缓存中的文件(操作系统必须执行额外的复制)和系统调用开销之间存在一个很小的速度差异。但出于您的目的,您可能应该坚持使用CRT文件函数
(从通用操作系统的角度) 为什么MMF会在页面文件中放一些东西?MMF页面由打开的数据文件支持,而不是页面文件。我同意Ben的观点。复制到页面文件似乎不太可能。是的,使用MMF显式避免了页面文件。但请注意“当将大型文件映射到虚拟内存以对其执行I/O操作时,请注意这样一个事实,即您在虚拟内存中烧掉的每个地址都是应用程序无法使用的地址。使用常规文件I/O例程对大型文件执行读/写操作通常效率更高。”