我是NEON内部函数的初学者,我想同时使用uint8x16_t
和uint8x16x4_t
。在使用它时,我遇到了一种情况,我想从uint8x16_t
中提取一个字节。由于过于天真,我在运行时不小心开始使用[]
运算符从中提取字节。但是我的编译器CLANG高兴地编译了代码,没有给出错误或警告,并且得到了所需的输出。
我搜索了ARM参考指南,但似乎没有找到关于在[]
向量上使用uint8x16_t
运算符的参考,毕竟它是128位寄存器而不是数组! (如果我错了,请纠正我)。
因此,为了弄清这个问题,我在头文件uint8x16_t
中跟踪了向量arm_neon.h
的来源,然后发现了这一点:
typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t;
此内容如何存储在计算机内存中?
为什么我应该直接在其上使用[]
运算符正在使用:
uint8_t fetch(uint8x16_t * r,int index){ 未签名的字符u [16]; vst1q_u8(u,* r); 返回u [index]; }
而不是:
uint8_t提取(uint8x16_t * r,整数索引){ 返回(* r)[index]; } //这在性能上要快得多!
每一个帮助将不胜感激!
为什么我可以直接在其上使用
[]
运算符
因为gcc / clang用GNU C本机向量(https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html)定义了它,对于操作符确实有明确定义的规则。
[ARM的文档可能不能保证[]
可以工作,并且可能有些ARM编译器不起作用。
它与其他任何类型的存储在内存中(或如果存储在寄存器中或未优化,则不存储)。对象表示在最低地址处具有最低元素。 uint8x16_t
对象在大多数方面都类似于int
对象,就编译器而言,它们可以决定将其保留在哪里并对其进行优化,等等。