Noe*_*elC 5 c++ assembly sse vector
由于我只能使用SSE和SSE2指令的约束,我需要用另一个向量中的0元素替换4元素__m128i向量的最低有效(0)元素.
对于浮点向量,任务很简单 - 可以使用_mm_move_ss()内在函数来使元素被另一个向量中的0元素替换.它生成一个movss指令,因此效率很高.
使用两个转换内在函数,也可以说服编译器使用单个SSE movss指令来移动整数数据.源代码最终看起来像这样:
__m128i NewVector = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(Take3FromThisVector),
_mm_castsi128_ps(Take1FromThisVector)));
Run Code Online (Sandbox Code Playgroud)
它看起来有点乱,但是通过适当的评论量可以接受,特别是因为它产生了最少的指令.在其典型用途中,所有内容都经过优化,可以在xmm寄存器中使用.
我的问题是:
因为它是一个movss指令,其中"ss"意味着单精度浮点,是否可以移动整数数据,这些数据可能包含某些"特殊"或"非法"(用于浮点)任何一个位的组合矢量位置?
显而易见的替代方案 - 我也实现并测试过 - 是使用掩码对第一个向量进行AND运算,然后在第二个向量中使用OR,该向量仅包含最低有效元素中的一个值,其他所有值均为零.可以想象,这会产生更多指令.
我已经测试了我上面展示的转换方法并且它似乎没有引起任何问题,但我特别注意到没有为整数数据执行相同操作的内在提供.似乎英特尔会提供一个,如果它对整数数据一样好 - 例如,_mm_move_epi32或类似的.所以我怀疑这是不是一个好主意.
我做了一些搜索,例如"可以使用movss指令导致浮点异常",但没有找到任何可以回答我问题的信息.
提前感谢您愿意分享的知识.
-Noel
是的,movss xmm, xmm在整数数据上使用FP shuffle是很好的.insn参考手册告诉你它不能引发FP数字异常; 只有实际的FP数学指令才能做到.所以继续演员.
甚至没有使用FP在大多数uarches整数数据洗牌(但使用FP运算指令之间的整数洗牌额外的延迟)旁路延迟.
Agner Fog的"优化组装"指南有一个很好的部分,说明哪些指令对不同类型的数据移动(广播,合并等)有用.另请参阅x86标记wiki以获得更多好的链接.
没有整数固有的原因是SSE2 movd整数指令将目标的高位字节归零,就像movss用作加载一样,但不同于movss寄存器之间.
英特尔的矢量指令集以其不一致性和非正交性而着称,尤其是 最早的版本(如SSE1).SSE4.1填补了许多空白,但仍有明显缺失的部分.