【发布时间】:2017-07-06 00:00:02
【问题描述】:
我正在寻找一种尽可能快的哈希/校验和算法,同时仍然能够检测到对 4096 字节内存页面的更改。因为大小是固定的,所以我希望有可能为此目的获得优化的算法,因为保证大小不会改变。
我正在做的是对一些内存页面进行校验和,进行操作,然后再次对页面进行校验和以查看它们是否已更改。由于空间原因,简单地按字节与旧字节的副本进行比较是不可行的。我不需要知道更改发生在页面的哪个位置,只要发生更改,比较校验和就足够了。
我在硬件和 xxHash 中尝试过 CRC32,都取得了不错的效果。不过,据我所知,它们并不是为固定大小的缓冲区量身定制的。
编辑:这是我在硬件中用于 CRC32 的代码。由于某种原因,它比 xxHash 慢。
// Warning! Not padding, so don't use if length isn't dividable by sizeof(uint32_t).
uint32_t sse42_crc32_32bit(const uint32_t* buffer, const uint32_t length)
{
uint32_t crc = 0;
const uint32_t numRounds = length / sizeof(uint32_t);
for (uint32_t i = 0; i < numRounds; ++i)
{
crc = _mm_crc32_u32(crc, buffer[i]);
}
return crc;
}
【问题讨论】:
-
您预计大部分是命中还是大部分未命中?如果您预计缓冲区会发生很大变化,那么您可以使用非常快的方法(如直接求和),然后使用更慢且更可靠的方法来清除误报?
-
您是否必须跟踪每一次更改,或者您可以承受错过一些?
-
值得一试,
fork考虑到所有因素都相当便宜,但您的 CRC 想法也可能是可行的。调试器可以做一些非常疯狂的事情,因为这种功能有操作系统挂钩,所以我敢打赌,你可以在纯用户模式代码中走得很远。 -
CRC32c 将检测到all changes with Hamming distance 4 or less up to roughly 2³¹ bits。大多数典型的散列函数(如 xxHash)没有——也不能,在设计上——给你这个保证。
-
您正在以缓慢的方式使用 _mm_crc32_u32,纯粹是串行的。有关预期用途,请参见例如this。 E:在您的情况下,您不妨计算单独的 CRC 并将它们全部进行比较,这比合并它们更容易,并且实际上漏报更少。
标签: c++ windows hash compare checksum