_mm512_popcnt_epi64
является частью AVX512-VPOPCNTDQ. 256-битные и 128-битные версии также требуют, чтобы AVX512VL использовал инструкции AVX512 со 128 или 256-битными векторами.
Все основные процессоры AVX512 имеют AVX512-VL. В процессорах Xeon Phi нет AVX512-VL.
Возможно, вы забыли включить необходимые параметры компилятора (например, GCC -march=native
, чтобы включить все, что может делать машина, на которой вы компилируете), или вы компилируете для цели, у которой нет обеих функций. Если это так, то у компилятора не будет определения _m256_popcnt_epi64
как внутреннего, поэтому в C он примет свою и необъявленную функцию и вызовет ее. (Что, конечно, не будет найдено во время ссылки.) И / или он предупредит или выдаст ошибку (C или C ++) о том, что прототип не найден.
В настоящее время очень немногие процессоры имеют AVX512-VPOPCNTDQ (wikipedia AVX512 функция по сравнению с матрицей ЦП):
- Knight's Mill (Xeon Phi последнего поколения): только AVX512-VPOPCNTDQ, без AVX512VL. Таким образом, для
gcc -O3 -march=knm
доступны только __m512i
версии. Вам определенно следует использовать 512-битные векторы на Xeon Phi, если схема данных не работает идеально для 256 и потребует дополнительного перетасовки для 512-бит. Но будьте осторожны, это медленно для некоторых инструкций AVX / AVX2, у которых нет 512-битных версий, например, перемешивание с элементами меньше 32-битных. (Нет AVX512 BW)
- Ice Lake / Tiger Lake: имеет как AVX512 VPOPCNTDQ, так и AVX512 VL, поэтому при компиляции для этой целевой микроархитектуры поддерживается
_mm256_popcnt_epi64
, например gcc -O3 -march=icelake-client
. (Предполагая, что заголовки вашего компилятора верны).
Выбор между 256 или 512-битными векторами в Ice Lake - это компромисс, как и в Skylake-x: когда 512-битные векторные мопы находятся в полете, векторные ALU на порту 1 не используются. И максимальная тактовая частота турбо может быть снижена. Инструкции SIMD, снижающие частоту ЦП. Поэтому, если вы не получаете большого ускорения от более широких векторов (например, из-за узкого места в памяти или ваши циклы SIMD являются лишь крошечной частью более крупной программы), использование 512-битных векторов в одном цикле может снизить общую производительность.
Другие процессоры вообще не имеют аппаратной поддержки SIMD popcnt, и форма _mm512_popcnt_epi64
недоступна.
Даже если у вас есть только AVX2, а не AVX512 вообще, SIMD popcnt лучше скалярных popcnt
над немаленькими массивами на современных процессорах с быстрым vpshufb
(_mm256_shuffle_epi8
). https://github.com/WojciechMula/sse-popcount/ strong> имеет версии AVX2 и AVX512, которые используют vpternlogd
для накопления Harley-Seal, чтобы уменьшить количество запросов SIMD LUT для поп-счета.
Также в разделе «Переполнение стека» Подсчет 1 бита (подсчет населения) для больших данных с использованием AVX-512 или AVX-2 показывает, что некоторый код скопирован из этого репо пару лет назад.
Если вам нужны подсчеты для отдельных элементов по отдельности, просто используйте стандартную распаковку для vpshufb
и vpsadbw
против нулевого вектора в hsum на 64-битные блоки qword.
Если вам нужно позиционное число (отдельная сумма для каждой битовой позиции), см. https://github.com/mklarqvist/positional-popcount.
person
Peter Cordes
schedule
18.05.2020