Aarch64 NEON 中的 UADDL 与 UADDL2

Posted

技术标签:

【中文标题】Aarch64 NEON 中的 UADDL 与 UADDL2【英文标题】:UADDL vs UADDL2 in Aarch64 NEON 【发布时间】:2017-12-11 16:26:54 【问题描述】:

NEON 组装

我正在尝试了解 arm-v8 NEON。让我举个例子,我想做什么。

我从数组 A 加载 16 字节(uchar 中的像素)。现在我想尝试“延长 ADD”到 ushort。从文档中,我看到UADDL and UADDL 将分别为源寄存器的下半部分和上半部分做加长加法。我可以编写以下代码来让它工作:

ld1 V10.16B, [x0]

uaddl V11.8H, V10.8B, V10.8B    
uaddl2 V12.8H, V10.16B, V10.16B 

st1 V11.8H, [x1], #16 
st1 V12.8H, [x1], #16 

NEON 内在函数

来到 NEON Intrinsics,语法如下:(Refer Page 8)

uint16x8_t vaddl_u8 (uint8x8_t a, uint8x8_t b)
uint16x8_t vaddl_high_u8 (uint8x16_t a, uint8x16_t b)

这里,两个函数的输入是不同类型的。

所以一旦我加载了一个 uint8x16_t 变量,我应该如何将此变量传递给 vaddl_u8?我可以做任何铸造吗?还是我必须将下半部分复制到另一个变量? (也就是说,这是额外的费用)

所以我的问题是,如何使用 NEON 内部函数实现这段汇编代码?


更新

    我在 Ubuntu 16.04 中使用 aarch64-linux-gnu-g++(gcc 版本 5.4.0)。

【问题讨论】:

您可以免费将uint8x16_t 转换为uint8x8_t,对吗?我认为具有演员阵容。对下半部分执行此操作,它应该编译为您希望的 asm。 对不起,我不明白你的问题。 @PeterCordes :这就是我正在寻找的,但找不到。 【参考方案1】:

您应该知道uint8x16_tuint8x8_t 是不同的数据类型。

下面是我要做的:

uint8x16_t a, b, c;
uint8x8_t low, high;
.
.
.
a = vld1q_u8(pSrc);

low = vget_low_u8(a);
high = vget_high_u8(a);

b = vaddl_u8(low, low);
c = vaddl_u8(high, high);

vst1q_u8(pDst++, b);
vst1q_u8(pDst++, c);

顺便说一句,请问你的vaddl_high_u8 来自哪里???

android Studio 3.0.1 上的自动完成功能并未将其显示为可行的选项。

【讨论】:

更新问题。我在 Ubuntu 16.04 中使用 gcc 您好,感谢您的回答。我不知道 vget_low_u8。但这也会导致额外的成本,对吧?我的意思是你需要调用 2 个额外的指令来重新排列数据。但在组装中,它不是必需的。所以我想知道intrisic中是否有可以直接将寄存器的下半部分传递给vaddl函数的东西。 @AbidRahmanK 一点也不,只要编译器还不错。 vget_low/highvreinterpret 之类的内容不会转化为附加说明。这就是它应该是最后的样子。它们就像 C 中的类型转换一样,基本上不会花费任何额外的周期。如果您可以编写程序集,为什么还要使用内在函数?这真的没有意义,因为即使是最新的编译器也会生成 FUBAR 机器代码。 @AbidRahmanK:gcc6.3 似乎也很糟糕。 vget_low_u8 / high 确实编译为实际的 dup 指令,而不是仅使用将 q0 别名为 get_low 的 d0 寄存器。 (godbolt.org/g/8sfYoS)。如果您尝试使用 vaddl_high_u8 避免 vget_high(无法在 AArch64 上优化),则 vget_low 编译为存储 q0 / reload d0。 (如果你先添加低半部分,那么它还必须重新加载 q0。)Jake 是对的:ARM 编译器仍然无法使用内在函数,这与 x86 不同,x86 中内在函数相当可靠地编译为体面的代码。 @AbidRahmanK:请参阅***.com/questions/38552116/…,尤其是指向 Matt Godbolt 的 CppCon2017 演讲的链接:“What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid”

以上是关于Aarch64 NEON 中的 UADDL 与 UADDL2的主要内容,如果未能解决你的问题,请参考以下文章

ARM NEON 到 aarch64

Debug系列aarch64下unrecognized command line option ‘-mfpu=neon‘

aarch64 上未对齐 SIMD 加载/存储的性能

AArch64 - 并行运行 ARM 和 ASIMD 指令

优化系列汇编优化技术:ARM架构64位(AARCH64)汇编优化及demo

NEON 汇编代码在 Cortex-A72 与 Cortex-A53 上需要更多周期