2016-07-30 29 views
2

ARM内在函数包括提取不同大小标量的函数。功能被最完全地记录在ARM® C Language Extensionsvgetq_lane_u64(x,0)与vget_low_u64(x)

ET vgetQ_lane_ST(T vec, const int lane); 

获取从输入向量指定车道的值。有12个内在函数。

和:

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

得到一个128位向量的高或低,一半。内部函数有24 。

我知道在某些情况下存在等价性。例如,小端机器上,以下为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); 

我的问题是,什么是实际差异,因为这两个函数返回一个标量?应该比另一个更受欢迎吗?

+0

'在小端机器上'可能不相关,因为在任何时候你都没有索引一个数组。索引矢量寄存器中的元素更像是标量寄存器中整数的左/右移位。我没有看过,但我认为可以以任何一种字节顺序运行的体系结构不会改变洗牌向量的指令的行为,也不会改变向量中插入/提取标量的行为。 (当然,如果标量来自内存,则字节顺序对标量内的字节顺序很重要,而不是向量内的元素位置。) –

回答

4

我会考虑重叠的实现细节。 “...因为两个函数都返回一个标量”并非如此,对于初学者来说:vgetq_lane_u64()返回一个uint64_t,这是一个标量; vget_low_u64()返回一个uint64x1_t,这是一个单位长度的向量。想想看,这家伙还存在:

uint64_t vget_lane_u64(uint64x1_t v, const int lane) 

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

+0

*“”...因为两个函数都返回一个标量“并不均匀真的......“ - 噢,你说得对;我错过了那个细节。看起来GCC和Clang大多是适应性的,因为它们在没有警告的情况下在'uint64_t'和'uint64x1_t'之间进行转换。 – jww

+0

本来我认为区别在于在大端和小端之间移动的方便性。也就是说,我可以#定义车道号,并根据大小写字母改变定义。 – jww

+2

@jww注意[GCC向量扩展](https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html#Vector-Extensions)([同样为Clang](http://clang.llvm。 org/docs/LanguageExtensions.html#vectors-and-extended-vectors)) - 你可以用NEON类型获得很多可怕的东西。 – Notlikethat

相关问题