【问题标题】:SSE2 instruction to convert a 8x16 register to two 4x32 registers having the even and odd indexed elementsSSE2 指令将一个 8x16 寄存器转换为两个具有偶数和奇数索引元素的 4x32 寄存器
【发布时间】:2013-05-19 22:08:51
【问题描述】:

是否有任何 SSE2 指令将一个 8x16 寄存器转换为两个 4x32 寄存器,一个 4x32 寄存器具有来自 8x16 寄存器的奇数索引元素,另一个具有偶数索引元素?请提出建议。

【问题讨论】:

  • 您将要添加“x86”和“程序集”标签或“c”和/或“c++”标签以明确您想要在哪个标签中。(程序集或内在函数)
  • 操作数是否有符号会有所不同,因为在复制到新的 4x32 格式时,您需要对数据进行零扩展或符号扩展。签名还是未签名?
  • 操作数已签名。

标签: c x86 intrinsics sse2


【解决方案1】:

请注意确定是否有一个单独的指令,但这样的东西应该可以工作(未经测试):

; Assume that the 8 16-bit values are in xmm0
PSHUFLW xmm1,xmm0,0D8h  ; Change word order to 3120 in the low qword
PSHUFHW xmm1,xmm1,0D8h  ; Change word order to 3120 in the high qword
PSHUFD xmm1,xmm1,0D8h   ; Change dword order to 3120
MOVAPD xmm0,xmm1        ; Copy to xmm0
PUNPCKLWD xmm0,xmm0     ; Expand even words to dwords
PUNPCKHWD xmm1,xmm1     ; Expand odd words to dwords
PSLLD xmm0,16           ; Sign-extend
PSRAD xmm0,16           ; ...
PSLLD xmm1,16
PSRAD xmm1,16

xmm0 现在应该包含 4 个偶数字,符号扩展为 32 位,xmm1 应该包含奇数字。

如果您可以使用 SSE4.1 指令,则可以稍微简化符号扩展部分。对于偶数词 (xmm0),您可以将 unpack 和两个班次替换为:

PMOVSXWD xmm0,xmm0

【讨论】:

  • 不应该是psrad吗?
  • 可以使用SSE4.1指令。
  • @harold:很好。固定。
  • 感谢迈克尔的回答...非常感谢您的帮助 :-)
【解决方案2】:

未经测试:

movdqa xmm1, xmm0
pslld xmm0, 16
psrad xmm1, 16  ; odd words
psrad xmm0, 16  ; even words

应该很容易转换为内在函数。

没有针对此的单一指令,即使在更高版本的 SSE 中也是如此。多输出非常少见,主要用于旧指令。

来自 SSE4.1 的pmovsxwd 使用(对于这个问题)错误的元素子集,即底部 4。

【讨论】:

  • 如果您要对多个向量进行操作并且在 SNB 或 IVB 上,使用 PSHUFB 而不是 PSLLD 可能是一个小胜利,因为它可以使用与班次不同的端口.然而,这真的很离谱,而且您的答案非常出色(此外,PSLLD 在较旧的内核上轻松获胜)。
  • @StephenCanon 很有趣,我没想到。将 shuffle-mask 放在那里可能有点烦人,palignr 也可以,对吧?还可以连接到 Sandy 上的另一个端口(您从哪里获得 IVB 的列表?),并且比 Core2 65nm 上的 pshufb 慢得多,我认为各方面都有优势
  • @harold:IVB 没有端口列表,但它是 SNB 的“托克”,所以问题端口应该相同。
  • 感谢大家的回复
猜你喜欢
  • 2013-05-11
  • 2011-01-31
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2013-03-22
相关资源
最近更新 更多