C++ 向量中的内部元素

C++ 向量中的内部元素,c++,optimization,arm,simd,neon,C++,Optimization,Arm,Simd,Neon,我想用Neon intrinsic优化这样的代码。基本上在给定的输入 012345678 将产生产出, 2110543876 获取3个向量,然后从src[2]、src[1]、src[0]访问每个元素并写入内存 有人能帮忙吗 谢谢。这在底层指令集中非常容易,因为您正在交换三元素结构的两个元素,这实际上已经说明了相关的指令: vld3.u8 {d0-d2}, [r0] vswp d0, d2 vst3.u8 {d0-d2}, [r0] 在中甚至有这个确切的例子,因为它是RGB-BGR转换,这正是N

我想用Neon intrinsic优化这样的代码。基本上在给定的输入

012345678

将产生产出,

2110543876

获取3个向量,然后从src[2]、src[1]、src[0]访问每个元素并写入内存

有人能帮忙吗


谢谢。

这在底层指令集中非常容易,因为您正在交换三元素结构的两个元素,这实际上已经说明了相关的指令:

vld3.u8 {d0-d2}, [r0]
vswp d0, d2
vst3.u8 {d0-d2}, [r0]
在中甚至有这个确切的例子,因为它是RGB-BGR转换,这正是NEON设计的处理方式

对于intrinsics,它有点棘手,因为没有
vswp
的内在特性;您只需用C语言表达它,并相信编译器会做正确的事情:

uint8x8x3_t data = vld3_u8(src);
uint8x8_t tmp = data.val[0];
data.val[0] = data.val[2];
data.val[2] = tmp;
vst3_u8(dest, data);

也就是说,由于手头的编译器是各种版本的GCC,我没能说服他们中的任何一个真正发出
vswp
——代码生成从次优到愚蠢不等。Clang做得更好,但仍然没有vswp;其他编译器可能更聪明。

这应该是相当严格的,使用
VTBL
VEXT
一次处理3 x 16字节的向量,以处理每个向量的不同“阶段”。你能分享示例代码吗?我现在真的没有时间编写完整的解决方案,但是,看看ARM文档,上面的两个说明应该是不言而喻的。谢谢你的回答。我使用“vld3q_u8”而不是“vld3_u8”,内部函数的结果似乎更好,但我在汇编中实现了它,但是“vld3.u8{d0,d2,d4}”在每个寄存器中只加载8个元素。查看参考“vld3q_u8”相当于“vld3.8{d0,d2,d4}”,使用
vld3q_u8
内在函数一次执行16个元素,实际上将产生两个
vld3.u8
指令-即
vld3.8{d0,d2,d4}[r0]!;vld3.8{d1,d3,d5},[r0]
(最后有两个存储区,但至少可以使用Q寄存器进行一次交换)。对于某些CPU来说,这可能会导致不太理想的结果,这些CPU希望加载和存储尽可能交替,而不是集中在一起,但无论如何都要选择机器上最快的。
vld3.u8 {d0-d2}, [r0]
vswp d0, d2
vst3.u8 {d0-d2}, [r0]
uint8x8x3_t data = vld3_u8(src);
uint8x8_t tmp = data.val[0];
data.val[0] = data.val[2];
data.val[2] = tmp;
vst3_u8(dest, data);