答案 0 :(得分:4)
这种行为看起来很不合逻辑。我想知道如果我们尝试一些愚蠢的事情会发生什么。如果整个文件大于512MB,您可以再次比较最后一部分的完整512MB而不是剩余的大小。
类似的东西:
if(remainder > 0)
{
cout << "segment size = "
<< remainder
<< " bytes for the remaining round";
if (size > segment_size){
block_size = segment_size;
offset = size - segment_size;
}
else{
block_size = remainder;
offset = segment_size * i
}
if(!segment_compare(block_size, offset)) return false;
}
这似乎是一件非常愚蠢的事情,因为我们会比较文件两次的部分内容,但如果您的分析数据准确,则应该更快。
它不会给我们一个答案(但是)如果确实更快它意味着我们正在寻找的响应在于你的程序对小块数据的作用。
答案 1 :(得分:2)
您要比较的文件有多碎片?您可以使用FSCTL_GET_RETRIEVAL_POINTERS
获取文件映射到磁盘的范围。我怀疑最后25 MB会有很多小范围来说明你测量的性能。
答案 2 :(得分:2)
我想知道当一个段的大小不是偶数页时,mmap是否表现得很奇怪?也许您可以尝试通过逐渐减小段大小来处理文件的最后部分,直到达到小于mapped_file_source :: alignment()的大小并专门处理最后一点。
另外,你说你正在做512MB的块,但是你的代码将大小设置为8 <&lt; 10。然后它乘以mapped_file_source :: alignment()。 mapped_file_source :: alignment()真的是65536吗?
我建议,为了更加便携并减少混淆,您只需使用模板参数中给出的大小,并且只需要在代码中将其设置为mapped_file_source :: alignment()的偶数倍。或者让人们通过两个人的力量开始为块大小或其他东西。将块大小作为模板参数传入然后乘以一些奇怪的实现定义常量似乎有点奇怪。
答案 3 :(得分:2)
我知道这不是你问题的确切答案;但是你有没有尝试过撇开整个问题 - 即只是一次性映射整个文件?
我对Win32内存管理知之甚少;但是在Linux上,您可以将MAP_NORESERVE
标志与mmap()
一起使用,因此您无需为整个文件大小保留RAM。考虑到你只是从两个文件中读取,如果内存不足,操作系统应该可以随时丢弃页面......
答案 4 :(得分:1)
我会在Linux或BSD上尝试,只是为了看看它是如何起作用的,出于好奇。
我有一个非常粗略猜测问题: 我敢打赌,Windows正在进行大量的额外检查,以确保它不会映射到文件的末尾。在过去,某些操作系统存在安全问题,允许mmap用户查看文件系统私有数据或来自地图末尾区域内其他文件的数据,因此对于操作系统设计人员来说,这里要小心。因此,Windows可能会使用更加谨慎的“将数据从磁盘复制到内核,将未映射的数据清零,将数据复制到用户”而不是更快“将数据从磁盘复制到用户”。
尝试映射到文件末尾,不包括不适合64K块的最后一个字节。
答案 5 :(得分:0)
病毒扫描程序是否会导致这些奇怪的结果?你试过没有病毒扫描程序吗?
此致
Sebastiaan