vgetq_lane_u64(x, 0) 与 vget_low_u64(x)

vgetq_lane_u64(x, 0) versus vget_low_u64(x)

ARM 内部函数包括提取不同大小标量的函数。这些函数在 ARM® C Language Extensions:

中有最完整的记录
ET vgetQ_lane_ST(T vec, const int lane);

gets the value from the specified lane of an input vector. There are 24 intrinsics.

并且:

T vget_high_ST(T2 a);
T vget_low_ST(T2 a);

gets the high, or low, half of a 128-bit vector. There are 24 intrinsics.

我知道在某些情况下存在等价关系。例如,在小端机器上,以下内容适用于 64 位值:

uint64x2_t x = ...;
vgetq_lane_u64(x, 0) == vget_low_u64(x);

高车道存在类似的等价关系:

uint64x2_t x = ...;
vgetq_lane_u64(x, 1) == vget_high_u64(x);

我的问题是,因为两个函数 return 都是标量,所以实际区别是什么?应该优先选择一个吗?

我认为重叠是一个实现细节。 “...因为两个函数 return 一个标量”甚至不正确,对于初学者来说:vgetq_lane_u64() returns a uint64_t,这是一个标量; vget_low_u64() returns a uint64x1_t,这是一个单位长度的向量。考虑到这个人也存在:

uint64_t vget_lane_u64(uint64x1_t v, const int lane)

从语义上讲,只要有向量操作输出的 Q 寄存器,并且需要将其拆分以将数据传递到 D 寄存器上的进一步向量操作,请使用 vget_{high,low}。当您实际提取单个值以传递给标量代码时,请使用 vget{,q}_lane。我很确定单位长度向量类型和标量类型之间的隐式转换实际上并不能在任何地方得到保证,所以我当然不会依赖它。