使用 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 的软件实现更快。
我目前正在尝试使用 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 的软件实现更快。