2

I wish to performance a conversion between __mmask16 and __m128i. However, as posted at https://stackoverflow.com/a/32247779/6889542

/* convert 16 bit mask to __m128i control byte mask */
_mm_maskz_broadcastb_epi8((__mmask16)mask,_mm_set1_epi32(~0))

_mm_maskz_broadcastb_epi8 and anything similar to it are not available on KNL yet. The lack of AVX512BW on KNL (Xeon Phi 7210) is really becoming a headache for me.

The origin of the problem is that I wish to take advantage of

_mm_maskmoveu_si128 (__m128i a, __m128i mask, char* mem_addr)

while using

__mmask16 len2mask[] = { 0x0000, 0x0001, 0x0003, 0x0007,
                         0x000F, 0x001F, 0x003F, 0x007F,
                         0x00FF, 0x01FF, 0x03FF, 0x07FF,
                         0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
                         0xFFFF };
Community
  • 1
  • 1
veritas
  • 176
  • 12
  • Might be a bit late but I'd suggest to simply precompute a `__m128i len2maskvector` table like your `__mmask16 len2mask` table and directly fetch the vector you want. That saves an instruction at the cost of 224 additional bytes in cache. If you need to do it from a mask: `kmov, popcnt (or lzcnt), loada`. – Christoph Diegelmann Jun 27 '17 at 11:44

1 Answers1

0

If you are actually intend to do generate something like:

__m128i mask = _mm_maskz_broadcastb_epi8(len2mask[length],_mm_set1_epi32(~0))

Why not just:

void foo(int length, char* mem_addr, const __m128i a)
{
    __m128i count = _mm_set_epi8(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
    __m128i mask = _mm_cmpgt_epi8(_mm_set1_epi8(length), count);
    _mm_maskmoveu_si128 (a, mask, mem_addr);
}

Godbolt demonstration.

chtz
  • 16,028
  • 4
  • 23
  • 52