2016-04-30 102 views
0

我试图让我的旧代码运行得更快,因为我发现RPi 2处理器支持NEON指令。所以我写了这样的代码:Raspberry Pi 2 NEON内联汇编指令不起作用

__asm__ __volatile__(
    "vld1.8 {%%d2, %%d3}, [%1];" 
    "vld1.8 {%%d4, %%d5}, [%2];" 
    "vaba.u8 %%q0, %%q1, %%q2;" 
    "vst1.64 %%d0, [%0];" 
    : "=r" (address_sad_intermediary) 
    : "r" (address_big_pic), "r" (address_small_pic) 
    : 
); 

然后在C中,主伤心变量与sad_intermediary求和。

主要目标是计算绝对差的总和,所以我从big_pic加载16 B到q1寄存器,从small_pic加载16 B到q2寄存器,计算SAD到q0,然后从q0加载低8 B到中介变量。问题是,由此产生的悲伤是零。

我使用GCC 4.9.2-std = C99 -pthread -O3 -lm -Wall -march = ARMv7的-一个-mfpu =氖vfpv4 -mfloat-ABI =硬选项。

您是否看到任何代码问题?谢谢。

回答

1

您从不将任何内容加载到q0中,因此vaba将绝对差值添加到未初始化的寄存器。它也看起来像你没有声明你正在修改哪些寄存器。

但我不知道这是你的问题的原因,因为我不太方便内联汇编。不过,你可能不应该使用内联汇编。如果你使用intrinsics那么编译器有更大的优化代码的能力。事情是这样的:

#include <arm_neon.h> 

... 
uint8x8_t s = vld1_u8(address_sad_intermediary); 
s = vaba_u8(s, vld1_u8(address_big_pic), vld1_u8(address_small_pic)); 
vst1_u8(address_sad_intermediary, s); 

(注意,此代码只能与八个字节的作品,因为你只保存在你的代码八个字节)

+0

但为什么我不加载任何的Q0?在这个[document,p58](https://people.xiph.org/~tterribe/daala/neon_tutorial.pdf)中,你可以看到,结果保存在第一个寄存器中,在我的情况q0中。 我不想使用内在函数,因为我读到性能对他们不理想。 –

+0

行内组装会使性能变差。内在性能历史上一直很糟糕,但gcc-6.1现在可用,而且现代Clang都做得很合理。只要代码简单,他们不应该搞砸,他们会处理管道调度,而不必考虑它。 – sh1

+0

'vaba'从q0中读取并增加q1和q2的绝对差值。在执行操作之前,你必须在q0中有一些东西,否则你会得到一个无意义的结果。 – sh1