Я написал векторизованные версии некоторых функций, которые в настоящее время являются узким местом алгоритма, используя для этого возможности Eigen.
Я также проверил, что AVX включен, убедившись, что EIGEN_VECTORIZE_AVX
определяется после включения Eigen.
Однако кажется, что моя функция никогда не вызывается с Packet8f
(AVX), если размер данных не кратен 8. Вместо этого она вызывается с Packet4f
(SSE).
Вот небольшое замечание: https://gist.github.com/bitonic/e89561cb21837b4dee8b5f49e1303919. Здесь я определяю операцию, используя Packet4f
и Packet8f
, а затем подсчитываю, сколько раз каждый вызывается с массивом размером 8 и 9. Когда массив имеет размер 8, версия Packet8f
вызывается один раз, как ожидается. Когда он имеет размер 9, версия Packet4f
вызывается дважды вместо одного вызова не векторизованной версии. Я проверил этот код на текущем мастере Эйгена 1d0c45122a5c4c5c1c4309f904120e551bacad02
.
Я немного откопал и считаю, что здесь происходит выбор пакета: https://gitlab.com/libeigen/eigen/blob/1d0c45122a5c4c5c1c4309f904120e551bacad02/Eigen/src/Core/util/XprHelper.h#L197.
Если я правильно понимаю, если размер данных не является динамическим c и не кратным 8 (это значение unpacket_traits<Packet8f>::size
), будет выбран полупакет, который соответствует тому, что показано выше для воспроизведения .
Если мое понимание верно, почему это так? Разве не должен быть выбран полный пакет с оставшимися элементами, работающими с невекторизованной операцией?
Может ли быть, что это условие неверно, и вместо этого должно быть сравнение> =, например, что-то вроде
template<int Size, typename PacketType,
bool Stop = Size==Dynamic || Size >= unpacket_traits<PacketType>::size || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
struct find_best_packet_helper;
вместо
template<int Size, typename PacketType,
bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
struct find_best_packet_helper;
Я убедился, что с исправлением, описанным выше, проблема исчезает.
Однако я могу неправильно понять, что здесь происходит, так как Я не очень хорошо разбираюсь во внутренних органах Eigen.