I managed to calculate the CRC on POWER which returns same CRC as intel CRC intrinsics (_mm_crc32_u16 , _mm_crc32_u64 , _mm_crc32_u8 and _mm_crc32_u32).
These functions takes an input CRC value in the first source operand, performs a CRC on the input value in the second source operand, and returns the output CRC value. The second source operand can be 8, 16, 32, or 64 bits.
The below functions should also replace ARM CRC32 methods __crc32cd , __crc32cw , __crc32ch , __crc32cb works on operands of 64 ,32,16,8 bits respectively.(Not tested)
uint32_t ppc_mm__crc32_u8(uint32_t crc, uint8_t v) {
uint32_t _crc = crc;
_crc ^= v;
for(int bit = 0 ; bit < 8 ; bit++) {
if (_crc & 1)
_crc = (_crc >> 1) ^ UINT32_C(0x82f63b78);
else
_crc = (_crc >> 1);
}
return _crc;
}
uint32_t ppc_mm__crc32_u16(uint32_t crc, uint16_t v) {
uint32_t _crc = crc;
_crc = ppc_mm__crc32_u8(_crc, v & 0xff);
_crc = ppc_mm__crc32_u8(_crc, (v >> 8) & 0xff);
return _crc;
}
uint32_t ppc_mm__crc32_u32(uint32_t crc, uint32_t v) {
uint32_t _crc = crc;
_crc = ppc_mm__crc32_u16(_crc, v & 0xffff);
_crc = ppc_mm__crc32_u16(_crc, (v >> 16) & 0xffff);
return _crc;
}
uint64_t ppc_mm__crc32_u64(uint64_t crc, uint64_t v) {
uint64_t _crc = crc;
_crc = ppc_mm__crc32_u32(static_cast<uint32_t>(_crc), v & 0xffffffff);
_crc = ppc_mm__crc32_u32(static_cast<uint32_t>(_crc), (v >> 32) & 0xffffffff);
return _crc;
}
References :
https://masterchef2209.wordpress.com/2020/06/17/guide-to-intel-sse4-2-crc-intrinisics-implementation-for-simde/
https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_crc32_u64&ig_expand=1497
------------------------------
Heena Bansal
------------------------------
Original Message:
Sent: Tue October 25, 2022 12:44 PM
From: Linda Alkire
Subject: C++ application string hash is broken on Power9
Heena - I spoke with one of my colleagues and here is his initial answer: "There's no easy answer. There is a reasonably simple algorithm behind the original question about _mm_crc32_u16
https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_crc32_u16&ig_expand=1493,1493. But I don't think there's an implementation for Power to point to, nor one that is Power-optimized."
He did mention that he will do a bit more digging to see if there's a better answer for you - I'll post here (or have him do so) if he has an update.
In the meantime, perhaps someone else in the community will chime in.
Thanks! Linda
------------------------------
Linda Alkire
IBM
Minneapolis MN
Original Message:
Sent: Fri October 21, 2022 01:54 PM
From: Heena Bansal
Subject: C++ application string hash is broken on Power9
Thanks Linda ! I really appreciate your response on this.
------------------------------
Heena Bansal
Original Message:
Sent: Fri October 21, 2022 01:51 PM
From: Linda Alkire
Subject: C++ application string hash is broken on Power9
HI Heena - let me see if I can find someone to answer this for you.
------------------------------
Linda Alkire
IBM
Minneapolis MN
Original Message:
Sent: Fri October 21, 2022 12:17 PM
From: Heena Bansal
Subject: C++ application string hash is broken on Power9
I am working on the C++ application whose some functionality is broken on POWER9.
Where crc16 is calculated for the Uint16 val .
static UInt64 crc32u16(UInt64 crc [[maybe_unused]], UInt16 val [[maybe_unused]])
{
#ifdef __SSE4_2__
return _mm_crc32_u16(crc, val);
#elif defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
return __crc32ch(crc, val);
#else
throw Exception("String hash is not implemented without sse4.2 support", ErrorCodes::NOT_IMPLEMENTED);
#endif
What replacement can be done in power9 ARCH for __crc32ch(crc, val) OR _mm_crc32_u16(crc, val);
I tried with
#elif defined(ARCH_PPC64LE)
return crc32_vpmsum(crc, reinterpret_cast<const unsigned char *>(&val), sizeof(val));
But , the hash value returned is different returned in x86(_mm_crc32_u16) and POWER(crc32_vpmsum)
------------------------------
Heena Bansal
------------------------------