Power Developer eXchange

 View Only
  • 1.  C++ application string hash is broken on Power9

    Posted Fri October 21, 2022 12:18 PM

    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
    ------------------------------


  • 2.  RE: C++ application string hash is broken on Power9

    Posted Fri October 21, 2022 01:52 PM
    HI Heena - let me see if I can find someone to answer this for you.

    ------------------------------
    Linda Alkire
    IBM
    Minneapolis MN
    ------------------------------



  • 3.  RE: C++ application string hash is broken on Power9

    Posted Fri October 21, 2022 01:55 PM
    Thanks Linda ! I really appreciate your response on this.

    ------------------------------
    Heena Bansal
    ------------------------------



  • 4.  RE: C++ application string hash is broken on Power9

    Posted Tue October 25, 2022 12:45 PM
    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
    ------------------------------



  • 5.  RE: C++ application string hash is broken on Power9

    Posted Wed October 26, 2022 10:10 AM

    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
    ------------------------------