或 __m128 中的元素

Posted

技术标签:

【中文标题】或 __m128 中的元素【英文标题】:OR elements in __m128 【发布时间】:2015-05-28 12:26:31 【问题描述】:

我正在编写一些 SSE 代码,我想对我的 __m128 中的所有元素进行 OR 运算。我可以单独获取所有值并以这种方式对它们进行 OR,但这似乎效率低下。

基本上我正在寻找的是 SPU 上可用的 orx 指令。这有点奇怪,所以没有直接的替代方案,但是有没有办法使用 SSE2 有效地做到这一点?

在我想做的代码中:

p = _mm_cmpgt_ps(p, r);
x = p[0] | p[1] | p[2] | p[3]; // spu_orx(p)

我可能在这一切都错了,我只需要重新设计代码,这样我就不会遇到这个问题,但我希望比我更有经验的人知道如何做到这一点!

【问题讨论】:

你真的想要每个 32 位值的 OR 吗?如果您只想知道 128 位中的一个是否非零,请使用 SSE4.1 中的!_mm_testz_si128 【参考方案1】:

这会将OR 所有 4 x 32 位元素放在一起:

p = _mm_or_si128(p, _mm_srli_si128(p, 8));
p = _mm_or_si128(p, _mm_srli_si128(p, 4));

元素 0 将包含最终值 - 如果需要,您可以将其提取为 int:

int result = _mm_cvtsi128_si32(p);

几个注意事项

当您发现自己需要执行这样的水平操作时,尤其是当它是性能关键的内部循环的一部分时,这通常表明您的 SIMD 实现效率低下,您可能需要重新考虑一下.

另请注意,尝试将 Cell SPU 代码逐行移植到 SSE 而不查看“全局”可能不会为您提供最佳结果。

【讨论】:

哦,我应该感谢您为社区提供的许多 SSE/bit-fiddling 答案 :) @legends2k:你真好 - 不过我很喜欢这样做! 我认为您需要旋转而不是移位,才能使每个元素具有相同的值。右移最右边的元素应该保持减少结果。这种旋转可以使用 shuffle 操作来完成。 谢谢保罗!这似乎符合我的要求,但我现在将尝试着眼于“大局”来重写它。 :-) 好吧,我正在尝试 OR 两个 _mm_cmpgt_ps 比较并将结果用作其他地方的掩码。目前我只是退后一步,看看我是否可以以不同的方式解决这个问题,也许在继续之前了解更多关于 SSE 的知识。似乎我可以使用 _mm_testz_si128,尽管我试图将自己限制在 SSE2。但这不是一个真正的问题,感谢您的建议!

以上是关于或 __m128 中的元素的主要内容,如果未能解决你的问题,请参考以下文章

为啥访问单个 SIMD 元素这么慢

从四个 __m128i 变量的 64 个高位或低位初始化 __m256i

__m128, SSE4 中最大绝对值的符号

将 __m128d 从 MASM 过程返回给 C 调用者

我的 CPU 中的 SSE 错误?

SSE 指令中的 UnsignedSaturate 是啥意思?