如何利用英特尔特定指令实现CRC32?

英特尔在SSE4.2指令集中提供了特定的CRC32指令 。 如何利用此指令加速CRC32计算?

首先,Intel的CRC32指令用于计算CRC-32C (即使用与常规CRC32不同的多项式。查看Wikipedia CRC32条目)

要使用gcc使用英特尔的CRC32C硬件加速,您可以:

  1. 通过asm语句在C代码中内联汇编语言
  2. 使用intrinsics _mm_crc32_u8_mm_crc32_u16_mm_crc32_u32_mm_crc32_u64 。 有关英特尔编译器icc的说明,请参阅“ 英特尔内部指南” ,但gcc也会实现它们。

这就是你如何使用__mm_crc32_u64一次占用一个字节,使用__mm_crc32_u64可以进一步提高性能,因为它一次需要8个字节。

 uint32_t sse42_crc32(const uint8_t *bytes, size_t len) { uint32_t hash = 0; size_t i = 0; for (i=0;i 

要编译它,您需要在CFLAGS传递-msse4.2 。 像gcc -g -msse4.2 test.c一样,它会抱怨对undefined reference to _mm_crc32_u8

如果要在可执行文件运行的平台中没有该指令, ifunc恢复为普通的C实现,可以使用GCC的ifunc属性。 喜欢

 uint32_t sse42_crc32(const uint8_t *bytes, size_t len) { /* use _mm_crc32_u* here */ } uint32_t default_crc32(const uint8_t *bytes, size_t len) { /* pure C implementation */ } /* this will be called at load time to decide which function really use */ /* sse42_crc32 if SSE 4.2 is supported */ /* default_crc32 if not */ static void * resolve_crc32(void) { __builtin_cpu_init(); if (__builtin_cpu_supports("sse4.2")) return sse42_crc32; return default_crc32; } /* crc32() implementation will be resolved at load time to either */ /* sse42_crc32() or default_crc32() */ uint32_t crc32(const uint8_t *bytes, size_t len) __attribute__ ((ifunc ("resolve_crc32"))); 

有关CRC-32C的快速硬件和软件实现,请参阅此答案 。 硬件实现有效地并行运行三条crc32指令以提高速度。