Да, в AVX512 семантика немного другая. Инструкции сравнения возвращают результаты в регистрах маски. У этого есть пара преимуществ:
- Регистры маски (8) полностью отделены от набора регистров
[xyz]mm
, поэтому вы не тратите впустую векторный регистр для результата сравнения.
- Существуют маскированные версии почти всего набора инструкций AVX512, что дает вам большую гибкость при использовании результатов сравнения.
Это требует немного другого кода по сравнению с устаревшей реализацией 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);
person
Jason R
schedule
04.01.2018