可以使用movss指令替换整数数据吗?

时间:2016-05-23 01:46:52

标签: c++ assembly vector sse

由于我只能使用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)));

它看起来有点乱,但是通过适当的评论量可以接受,特别是因为它产生了最少的指令。在其典型用途中,所有内容都经过优化,可以在xmm寄存器中使用。

我的问题是:

因为它是一个movss指令,其中“ss”意味着单精度浮点,是否可以移动可能包含某些“特殊”或“非法”(浮点)组合的整数数据任何向量位置的位数?

显而易见的替代方案 - 我也实现并测试了 - 是使用掩码对第一个向量进行AND运算,然后在第二个向量中使用OR,该向量仅包含最低有效元素中的一个值,其他所有值均为零。可以想象,这会产生更多指令。

我已经测试了上面展示的转换方法,它似乎没有引起任何问题,但我特别注意到没有提供对整数数据执行相同操作的内在函数。似乎英特尔会提供一个,如果它对整数数据一样好 - 例如,_mm_move_epi32或类似的。所以我怀疑这是不是一个好主意。

我做了一些搜索,例如“可以使用movss指令导致浮点异常”,但没有找到任何可以回答我问题的信息。

提前感谢您愿意分享的知识。

-Noel

2 个答案:

答案 0 :(得分:5)

是的,可以在整数数据上使用像movss xmm, xmm这样的FP shuffle。 insn参考手册告诉你它不能引发FP数字异常;只有实际的FP数学指令才能做到。所以继续演员。

在大多数搜索中,对整数数据使用FP shuffle甚至没有旁路延迟(但在FP数学指令之间使用整数混洗有额外的延迟)。

Agner Fog's "optimizing assembly" guide有一个很好的部分,说明哪些指令对不同类型的数据移动(广播,合并等)有用。另请参阅标记wiki以获取更多有用的链接。

没有整数内在的原因是SSE2 movd整数指令将目标的高位字节归零,例如movss用作加载,但与寄存器之间的movss不同。 / p>

英特尔的矢量指令集以其不一致性和非正交性而闻名,尤其是最早的版本(如SSE1)。 SSE4.1填补了许多空白,但仍有明显缺失的部分。

答案 1 :(得分:2)

__m128__m128i类型可以互换。演员表的主要原因是让你的意图更清晰(让你的编译器感到高兴)。演员本身不会产生任何额外的组装。

_mm_move_ss operation直接根据结果中的哪些位进行描述。

如果最终得到单精度浮点数的无效位组合,那么只有在尝试在浮点计算中使用结果值时才会出现问题。