【发布时间】:2022-01-16 10:31:18
【问题描述】:
是否有类似于xtn2 的操作,但实际上清除了下半部分而不是保持原样?我有一个 128 位向量 v0 其视图为 4s 是 {a,x,b,y} 与 x 和 y 无关。我想获得{0,0,a,b}。如果我这样做了
xtn2 v0.4s, v0.2d
mov v0.d[0], xzr
我得到了我想要的结果。有没有办法通过一条指令或更有效的方式来做到这一点?
【问题讨论】:
-
如果您可以备用另一个寄存器,那么
movi v1.4s, #0 ; xtn2 v1.4s, v0.2d可能会好一点,因为movi可以更早地执行乱序,而无需等待v0中的输入准备好。另外,我相信从通用寄存器到 SIMD 寄存器的移动非常缓慢,尽管我不知道这是否适用于零寄存器。 -
我想你已经考虑过是否可以重写后续代码以使用
{a, b, 0, 0},然后只使用xtn? -
也许
uzp2可以用来做这个。 -
@fuz:好地方。我认为它实际上是
uzp1 v0.4s, v1.4s, v0.4s,其中v1用零填充。这似乎是最好的答案 - 你仍然需要一个备用寄存器,但它可以始终保持为零,例如跨循环迭代。 -
@potuz:使用
uzp1,您无需在初始清零后写入第二个寄存器。如果您在循环中执行此操作,您可以在循环之前movi v1.4s, #0,并且每次迭代只有uzp1 v0.4s, v1.4s, v0.4s。使用xtn2,您会覆盖之前清零的寄存器,因此每次循环迭代都需要movi v1.4s, #0。
标签: assembly simd arm64 neon armv8