2015-07-02 59 views

回答

7

所有英特爾CRC32指令首先用於計算CRC-32C(即使用不同的多項式,定期CRC32看Wikipedia CRC32條目)。

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

    通過 asm聲明C代碼
  1. 聯彙編語言
  2. 使用內在_mm_crc32_u8_mm_crc32_u16_mm_crc32_u32_mm_crc32_u64。有關英特爾編譯器icc的描述,請參見Intel Intrinsics Guide,但gcc也可實現它們。

這是你將如何與__mm_crc32_u8,在一次接受一個字節,使用__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<len;i++) { 
    hash = _mm_crc32_u8(hash, bytes[i]); 
    } 

    return hash; 
} 

要編譯這一點,你需要通過-msse4.2CFLAGS。像gcc -g -msse4.2 test.c,否則它會抱怨undefined reference to _mm_crc32_u8

如果您希望恢復爲普通的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"))); 
1

請參閱this answer快速硬件和軟件實現CRC-32C。爲了提高速度,硬件實現有效地並行運行三條指令。

相關問題