【问题标题】:CRC32C SSE vs BOOSTCRC32C SSE 与 BOOST
【发布时间】:2024-01-06 00:59:01
【问题描述】:

我正在尝试优化我的一段运行 CRC32 检查的代码。

对于测试缓冲区,我做了以下操作:

char *buff = new char[1024];
for (int i = 0; i < 1024; ++i)
    buff[i] = i;

目前,我使用boost的crc实现如下:

boost::crc_optimal<32, 0x1EDC6F41, 0, 0> crc;
crc.process_bytes(buff, 1024);
unsigned int boostCRC = crc();

这意味着多项式“0x1EDC6F41”,初始值为0,最终异或为0。

然后,我写了最简单的sse4.2版本的crc32c算法:

unsigned int sseCRC = 0;
for (char *iter = buff, *end = buff + 1024; iter != end; ++iter)
    sseCRC = _mm_crc32_u8(sseCRC, *iter);

问题是,即使多项式应该相同,最终值也不匹配。有没有人有这方面的经验?我的 sse 版本有问题吗?

【问题讨论】:

  • 这几乎肯定是字节序问题。我懒得通读这两个函数的文档,但我建议你这样做(非常小心!),并检查它们如何确定字节序。
  • 由于 SSE 版本是固定多项式,我能想到的最好的办法就是将 boost 多项式翻转为 0x416FDC1E,以及在处理第一个字符后检查结果,它们立即发散.我最大的问题是关于 sse 版本的信息非常稀少,所以我希望在我开始挖掘档案之前,有人可能会根据我尝试使用 sse 版本的个人经验来提供答案。
  • 哦,还从 sse 版本中反转答案的字节顺序,以及使用 0xFFFFFFFF 测试异或

标签: visual-c++ boost sse


【解决方案1】:

根据Intel® SSE4 Programming Reference,CRC 指令进行位反射,在 boost CRC 模板中默认关闭。使用

boost::crc_optimal<32, 0x1EDC6F41, 0, 0, true, true> crc;

而不是

boost::crc_optimal<32, 0x1EDC6F41, 0, 0> crc;

将产生与 SSE 版本相同的校验和。

【讨论】: