c - _mm_crc32_u8 gives different result than reference code -
i've been struggling intrinsics. in particular don't same results using standard crc calculation , supposedly equivalent intel intrinsics. i'd move using _mm_crc32_u16
, , _mm_crc32_u32
if can't 8 bit operation work there's no point.
static uint32 g_ui32crc32table[256] = { 0x00000000l, 0x77073096l, 0xee0e612cl, 0x990951bal, 0x076dc419l, 0x706af48fl, 0xe963a535l, 0x9e6495a3l, 0x0edb8832l, 0x79dcb8a4l, 0xe0d5e91el, 0x97d2d988l, .... // basic 32-bit crc calculator // note: code cannot changed uint32 calccrc32(unsigned char *pucbuff, int ilen) { uint32 crc = 0xffffffff; (int x = 0; x < ilen; x++) { crc = g_ui32crc32table[(crc ^ *pucbuff++) & 0xffl] ^ (crc >> 8); } return crc ^ 0xffffffff; } uint32 calccrc32_intrinsic(unsigned char *pucbuff, int ilen) { uint32 crc = 0xffffffff; (int x = 0; x < ilen; x++) { crc = _mm_crc32_u8(crc, *pucbuff++); } return crc ^ 0xffffffff; }
that table different crc polynomial 1 used intel instruction. table ethernet/zip/etc. crc, referred crc-32. intel instruction uses iscsi (castagnoli) polynomial, crc referred crc-32c.
this short example code can calculate either, uncommenting desired polynomial:
#include <stddef.h> #include <stdint.h> /* crc-32 (ethernet, zip, etc.) polynomial in reversed bit order. */ #define poly 0xedb88320 /* crc-32c (iscsi) polynomial in reversed bit order. */ /* #define poly 0x82f63b78 */ /* compute crc of buf[0..len-1] initial crc crc. permits computation of crc feeding routine chunk of input data @ time. value of crc first chunk should zero. */ uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len) { int k; crc = ~crc; while (len--) { crc ^= *buf++; (k = 0; k < 8; k++) crc = crc & 1 ? (crc >> 1) ^ poly : crc >> 1; } return ~crc; }
you can use code generate replacement table code computing crc-32c of each of one-byte messages 0, 1, 2, ..., 255.
Comments
Post a Comment