使用 ARMv8 CRC Extension 计算 CRC-32/MPEG-2 Checksum

Use ARMv8 CRC Extension to calculate CRC-32/MPEG-2 Checksum

我目前正在尝试使用 ARMv8 CRC Instructions 来加速 CRC32/MPEG2 校验和的计算。

我发现的唯一 examples 使用这些指令计算常规 CRC32 校验和。

uint32_t ZLIB_INTERNAL armv8_crc32_little(unsigned long crc,
                                          const unsigned char *buf,
                                          z_size_t len)
{
    uint32_t c = (uint32_t) ~crc;

    while (len && ((uintptr_t)buf & 7)) {
        c = __crc32b(c, *buf++);
        --len;
    }

    const uint64_t *buf8 = (const uint64_t *)buf;

    while (len >= 64) {
        c = __crc32d(c, *buf8++);
        c = __crc32d(c, *buf8++);
        c = __crc32d(c, *buf8++);
        c = __crc32d(c, *buf8++);

        c = __crc32d(c, *buf8++);
        c = __crc32d(c, *buf8++);
        c = __crc32d(c, *buf8++);
        c = __crc32d(c, *buf8++);
        len -= 64;
    }

    while (len >= 8) {
        c = __crc32d(c, *buf8++);
        len -= 8;
    }

    buf = (const unsigned char *)buf8;

    while (len--) {
        c = __crc32b(c, *buf++);
    }

    return ~c;
}

区别,根据这个list seems to be that for CRC32/MPEG2 the input and output are not reflected和输出没有和0xFFFFFFFF异或。

我尝试使用上面的算法通过首先反转数据中的每个字节来计算 CRC32/MPEG2 校验和(我实际上只使用 0 的 1 个字节作为数据来暂时跳过这个)。然后将生成的 CRC32 与 0xFFFFFFFF 进行异或运算,然后反转,但结果不匹配。

For Example:
DATA = 0x00
CRC32 = 0xD202EF8D
CRC32/MPEG2 = 0x4E08BFB4

0xD202EF8D xor 0xFFFFFFFF = 0x2DFD1072
reverse( 0x2DFD1072 ) = 0x13822FED

从数学上讲,恐怕我已经无法理解了。甚至可以将 CRC32 计算的结果转换为 CRC32/MPEG2。有没有办法修改上面的计算例程?

谢谢

“反射”指的是位。对于具有相同多项式的非反射 CRC,您需要反转提供给它的每个字节的位。您可以使用 table 来做到这一点。然后您需要反转生成的 CRC 的位。

很想知道加上硬件指令是否比 CRC 的软件实现更快。