或 __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 中的元素的主要内容,如果未能解决你的问题,请参考以下文章