2016-04-30 15 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からq1レジスタに16B、small_picからq2レジスタに16Bをロードし、SADをq0に計算し、次にq0から下位8Bをロードします。中間変数。問題は、結果として得られる悲しみがゼロであることです。

私は-std = c99を-pthread -O3 -Wall -lm -march =のARMv7-A -mfpu =ネオンvfpv4ハード= -mfloat-ABIオプションでGCC 4.9.2を使用しています。

コードに問題はありませんか?ありがとう。

答えて

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); 

(あなただけのコードで8つのバイトを保存するので、このコードはわずか8つのバイトで動作することに注意してください)

+0

しかし、なぜ、私はQ0に何をロードしないではないのですか?この[document、p58](https://people.xiph.org/~tterribe/daala/neon_tutorial.pdf)には、結果が最初のレジスタq0に保存されていることがわかります。 パフォーマンスが理想的ではないことを読んだので、組み込み関数を使用したくありませんでした。 –

+0

パフォーマンスは、インラインアセンブリで悪化する可能性があります。 Intrinsicsのパフォーマンスは歴史的に恐ろしいものでしたが、gcc-6.1は現在利用可能です。それと現代のClangはどちらも合理的な仕事をしています。コードがシンプルである限り、彼らは混乱してはいけません。パイプラインのスケジューリングは、考えなくても処理できます。 – sh1

+0

'vaba'はq0から読み込み、q1とq2の絶対差を加算します。あなたは操作を実行する前にq0に何かを持っていなければなりません。さもなければナンセンスの結果が得られます。 – sh1

関連する問題