2016-04-30 103 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