При операциях сравнения sse2 или avx возвращались битовые маски всех нулей или всех (например, _mm_cmpge_pd возвращает __m128d.
Я не могу найти эквивалент с avx512. Кажется, что операции сравнения возвращают только короткие битовые маски. Произошли ли фундаментальные изменения в семантике или я что-то упустил?
Да, семантика немного отличается в AVX512. Инструкции сравнения возвращают результаты в регистрах маски. Это имеет пару преимуществ:
[xyz]mm
набор регистров, поэтому вы не тратите впустую векторный регистр для результата сравнения.Он требует немного другого кода по сравнению с устаревшей реализацией SSE / AVX, но это не так уж плохо.
Редактировать: Если вы хотите подражать старому поведению, вы можете сделать что-то вроде этого:
// do comparison, store results in mask register
__mmask8 k = _mm512_cmp_pd_mask(...);
// broadcast a mask of all ones to a vector register, then use the mask
// register to zero out the elements that have a mask bit of zero (i.e.
// the corresponding comparison was false)
__m512d k_like_sse = _mm512_maskz_mov_pd(k,
(__m512d) _mm512_maskz_set1_epi64(0xFFFFFFFFFFFFFFFFLL));
Возможно, есть более оптимальный способ сделать это, но я сам относительно плохо знаком с AVX512. Все маски могут быть предварительно рассчитаны и использованы повторно, так что вы, по сути, просто добавляете одну дополнительную инструкцию перемещения в маске, чтобы сгенерировать искомый искомый результат.
Изменить 2: Как предполагает Питер Кордес в комментарии ниже, вы можете использовать _mm512_movm_epi64()
вместо этого, чтобы упростить вышесказанное еще больше:
// do comparison, store results in mask register
__mmask8 k = _mm512_cmp_pd_mask(...);
// expand the mask to all-0/1 masks like SSE/AVX comparisons did
__m512d k_like_sse = (__m512d) _mm512_movm_epi64(k);
Других решений пока нет …