2011-05-16 163 views
3

大家下午好,我们正在使用Windows和Linux的内存映射文件API来构建一个Windows/LINUX演示程序的原型。我们的扣除器通过对要删除的所有数据库记录进行顺序扫描开始。因此,在我们对要被重复删除的数据库记录进行初始顺序扫描期间,我们将标志FILE_FLAG_SEQUENTIAL_SCAN传递给Windows API CreateFile。 一旦我们完成了我们的重复数据删除过程的第一部分,我们尝试使用Windows内存映射API来随机访问数据。此时,使用Windows C++ API,是否可以动态更改为FILE_FLAG_RANDOM_ACCESS模式?是否可以从FILE_FLAG_SEQUENTIAL_SCAN动态更改为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中。谢谢。

回答

5

传递给CreateFile()的缓存提示标志不会影响内存管理器满足通过取消引用映射节中的地址而生成的页面错误的方式。这样的I/O使用相同的 - 它们使用与常规I/O相同的缓存页面。

这就是说,当与FILE_FLAG_SEQUENTIAL_SCAN,高速缓存管理器可能进行预读操作(甚至可将整个文件读入内存,如果系统条件允许这一点)创建句柄到文件中。这意味着,如果顺序访问映射文件的页面,则可能会遇到更少的硬页面错误。

在我看来,通过简单地重复使用在您的删除处理过程中创建的句柄,您将获得最佳服务。关闭和重新打开可能会导致文件的先前缓存页面被丢弃,具体取决于缓存压力。

+0

谢谢你的回答。我刚接受你的回答。我将更改我们的代码以重用我们在重复数据删除处理期间创建的句柄。我们注意到,当使用FILE_FLAG_SEQUENTIAL_SCAN创建文件句柄时,我们顺序访问映射文件的页面时会遇到更少的硬页面错误。这是否意味着我们在重复数据删除处理期间不尝试使用FILE_FLAG_RANDOM_ACCESS?谢谢。 – Frank 2011-05-17 05:52:09

+0

@Frank - 您的里程可能会有所不同。当指定FILE_FLAG_RANDOM_ACCESS时,对于句柄将禁用预读。此外,缓存管理器在取消映射先前访问过的文件页面时不那么积极 - 这里的想法是在应用程序重新访问页面时最小化文件的映射/解映射事件。 – Bukes 2011-05-17 18:06:37

+0

谢谢你的回答。我想我们会尝试使用CreateFile(...,FILE_FLAG_RANDOM_ACCESS)运行我们的重复数据删除应用程序,以便在重复访问重复页面时尽量减少内存映射文件的映射/解映射事件。看到结果应该很有趣。谢谢。 – Frank 2011-05-18 01:43:58

3

如何FILE_FLAG_SEQUENTIAL_SCAN作品可以在这里找到的描述:http://support.microsoft.com/kb/98756

因为它只是与CreateFile函数使用,也没有办法,一旦文件被打开,以更新它。您可以随时关闭文件并用另一个标志重新打开文件。

+0

谢谢你的回答,我刚接受你的回答。你是否建议在我们的推理的第一个连续扫描阶段之后,我们关闭文件。然后,在最终的随机访问阶段,我们是否应该重新打开FILE_FLAG_RANDOM_ACCESS文件?这会影响我们使用Window Memory Mapping File API的能力吗?谢谢。 – Frank 2011-05-16 17:03:37

+0

我们现在正在尝试您的建议。所以我们:1.关闭(hFile)2. hFile = CreateFile((LPTSTR)TempFileName,.... Flags_ | FILE_FLAG_RANDOM_ACCESS); 3. Distance_.LowPart =(ULONG)FileSize_; Distance_.HighPart = 0; 4. dwPtr = :: SetFilePointer(hFile,Distance_.LowPart,&(Distance_.HighPart),FileBegin); 5. SetEndOfFile(hFile); 6. hMapping = :: CreateFileMapping(hFile,(SECURITY_ATTRIBUTES *)Security_,PAGE_READWRITE,0,0,0);谢谢。 – Frank 2011-05-16 17:18:42

+0

@Frank:您传递的标志不会影响文件I/O的正确操作,它只会影响缓冲效率。内存映射完全可能会完全绕过缓冲,我不确定这一点。 – 2011-05-16 17:20:32

0

只是备份@Burkes回答:因为你提到你是“使用Windows的内存映射文件API”,但应注意的是,Raymond Chen warns the cache hints have no affect on effect on memory mapped I/O

注:这些缓存提示只适用,如果你使用ReadFile(或道德等价物)。内存映射文件访问不通过缓存管理器,因此这些缓存提示不起作用。

因此,已经被缓存的内容可能会有所帮助,但未来的内存映射访问将无助于缓存被填充/删除。