我已经编写了一些函数的矢量化版本,这些函数目前是算法的瓶颈,使用 Eigen 的工具来做到这一点。
我还通过确保EIGEN_VECTORIZE_AVX在包含 Eigen 之后定义了 AVX 来检查是否启用了 AVX 。
但是,Packet8f如果数据大小不是 8 的倍数,我的函数似乎永远不会被(AVX)调用。相反,它被Packet4f(SSE)调用 。
这是一个小副本:https : //gist.github.com/bitonic/e89561cb21837b4dee8b5f49e1303919。在这里,我使用Packet4fand定义了一个操作Packet8f,然后计算每个使用大小为 8 和 9 的数组调用的次数。当数组大小为 8 时,Packet8f版本将按预期调用一次。当它的大小为 9 时,该Packet4f版本会被调用两次,再加上一次对非矢量化版本的调用。我已经在 Eigen 的当前 master 上测试了这段代码1d0c45122a5c4c5c1c4309f904120e551bacad02。
我挖了一点,我相信数据包选择发生在这里:https : //gitlab.com/libeigen/eigen/blob/1d0c45122a5c4c5c1c4309f904120e551bacad02/Eigen/src/Core/util/XprHelper.h#L197。
如果我理解正确,如果数据的大小不是动态的并且不是 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;
Run Code Online (Sandbox Code Playgroud)
代替 …