世界为什么_mm_crc32_u64(...)
这样定义呢?
unsigned int64 _mm_crc32_u64( unsigned __int64 crc, unsigned __int64 v );
该“CRC32”指令总是积累了32位CRC, 从来没有一个64位CRC(这是,毕竟,CRC32不CRC64)。 如果机器指令CRC32 恰好有一个64位目的地操作数,高32位被忽略,并用0填充的上完成,所以没有使用到EVER有一个64位的目的地。 我明白了为什么英特尔允许的指令(一致性)64位目的地操作数,但如果我想快速处理数据,我希望有一个源操作数尽可能大(即64位,如果我有剩多少数据,对于尾端),并总是32位目的地操作数小。 但内部函数不允许一个64位源和32位目的地。 注意其他内部函数:
unsigned int _mm_crc32_u8 ( unsigned int crc, unsigned char v );
的类型的“CRC”是不是8位的类型,也不是返回类型,它们是32位。 为什么没有
unsigned int _mm_crc32_u64 ( unsigned int crc, unsigned __int64 v );
? 英特尔指令支持这一点, 那就是最有意义的内在。
有没有人有移植的代码(Visual Studio和GCC)实施后的内在? 谢谢。 我的猜测是这样的:
#define CRC32(D32,S) __asm__("crc32 %0, %1" : "+xrm" (D32) : ">xrm" (S))
海湾合作委员会,并
#define CRC32(D32,S) __asm { crc32 D32, S }
对于VisualStudio中。 不幸的是我的约束是如何起作用知之甚少,并与语法和汇编级编程的语义一点经验。
小编辑:请注意,我定义的宏:
#define GET_INT64(P) *(reinterpret_cast<const uint64* &>(P))++
#define GET_INT32(P) *(reinterpret_cast<const uint32* &>(P))++
#define GET_INT16(P) *(reinterpret_cast<const uint16* &>(P))++
#define GET_INT8(P) *(reinterpret_cast<const uint8 * &>(P))++
#define DO1_HW(CR,P) CR = _mm_crc32_u8 (CR, GET_INT8 (P))
#define DO2_HW(CR,P) CR = _mm_crc32_u16(CR, GET_INT16(P))
#define DO4_HW(CR,P) CR = _mm_crc32_u32(CR, GET_INT32(P))
#define DO8_HW(CR,P) CR = (_mm_crc32_u64((uint64)CR, GET_INT64(P))) & 0xFFFFFFFF;
注意最后的宏语句多么不同。 缺乏统一的肯定和指示是内在尚未合理确定。 虽然没有必要把在显式(uint64)
在最后一个宏铸造,它是隐含的,确实会发生。 拆卸生成的代码的代码显示两个施放32-> 64和64-> 32,这两者都是不必要的。
换句话说,它是_mm_crc32_u64
, 不 _mm_crc64_u64
,但他们已经实现了它,仿佛它是后者。
如果我能得到的定义CRC32
上述正确的,那么我想改变我的宏
#define DO1_HW(CR,P) CR = CRC32(CR, GET_INT8 (P))
#define DO2_HW(CR,P) CR = CRC32(CR, GET_INT16(P))
#define DO4_HW(CR,P) CR = CRC32(CR, GET_INT32(P))
#define DO8_HW(CR,P) CR = CRC32(CR, GET_INT64(P))