下午好,我们正在使用Windows和Linux的内存映射文件API构建Windows / LINUX重复数据删除器的原型。我们的重复数据删除器首先对要删除的所有数据库记录进行顺序扫描。因此,在我们对要删除的数据库记录的初始顺序扫描期间,我们将标志FILE_FLAG_SEQUENTIAL_SCAN传递给Windows API CreateFile。 完成重复数据删除过程的第一部分后,我们尝试使用Windows内存映射API随机访问数据。此时,使用Windows C ++ API,是否可以动态更改为FILE_FLAG_RANDOM_ACCESS模式?
In Linux, we are are able to do this with the following excerpt of code,
MapPtr = (char*)mmap((void *)BaseMapPtr ,mappedlength,PROT_READ,
MAP_PRIVATE, hFile,baseoff );
if (MapPtr == MAP_FAILED){
perror("mmap");
throw cException(ERR_MEMORYMAPPING,TempFileName);
}
madvise(MapPtr,mappedlength,MADV_RANDOM);
我们是否在我们的重复数据删除过程的随机访问阶段使用FILE_FLAG_SEQUENTIAL_SCAN在Windows中支付罚金。谢谢。
答案 0 :(得分:5)
传递给CreateFile()的缓存提示标志不会影响内存管理器通过取消引用映射部分中的地址而生成的页面错误的方式。这样的I / O使用相同的 - 它们使用与常规I / O相同的缓存页。
也就是说,当使用FILE_FLAG_SEQUENTIAL_SCAN创建文件句柄时,缓存管理器可以执行预读操作(如果系统条件允许,甚至可以将整个文件读入内存) )。这意味着如果您按顺序访问映射文件的页面,则可能会遇到较少的硬页面错误。
在我看来,只需重新使用您在重复数据删除处理过程中创建的句柄,即可获得最佳服务。关闭和重新打开可能会导致文件的先前缓存页面被丢弃,具体取决于缓存压力。答案 1 :(得分:3)
有关FILE_FLAG_SEQUENTIAL_SCAN如何工作的说明,请访问:http://support.microsoft.com/kb/98756
由于它仅与CreateFile函数一起使用,因此打开文件后无法更新它。您可以随时关闭该文件并使用其他标志重新打开它。
答案 2 :(得分:0)
只是为了备份@Burkes回答:正如你提到的那样“你正在使用Windows的内存映射文件API”,应该注意Raymond Chen warns the cache hints have no affect on effect on memory mapped I/O:
注意:这些缓存提示仅在您使用ReadFile(或道德等价物)时适用。内存映射文件访问不通过缓存管理器,因此这些缓存提示无效。
所以已经缓存的内容可能会有所帮助,但未来的内存映射访问将无法帮助缓存填充/填充。