2012-02-16 18 views
2

アセンブラとNEONプログラミングを初めて使用しています。 私の仕事は、アルゴリズムの一部をNEON命令を使ってCからARMアセンブラに変換することです。 アルゴリズムはint32配列をとり、この配列から異なる値をロードし、ビットシフトとXorを実行して結果を別の配列に書き込みます。 後で私は64ビット値の配列を使いますが、今はコードを書き直そうとしています。私はこのようなレジスタをロードする場合ARM NEONアセンブラ - 使用方法と理解

1):

vld1.32 d0, [r1] 

はそれを埋めるためにメモリまたは2x32Bitからのみ32ビットをロードしますので、ここで

C Pseudo code: 

out_array[index] = shiftSome(in_array[index])^shiftSome(in_array[index]); 

は、NEON命令に関する私の質問です64Bit Neon D-Register?

2.)Dレジスタの2/4/8(i32、i16、i8)の部分はどのようにアクセスできますか?

3)私はオフセットで配列から異なる値をロードしようとしていますが、 がここに...私が間違って何をやっている...動作していないように私のコードです: (それはあります整数配列はそう - 私は、例えば、「」アレイであると64ビット= 8バイトのオフセットを有していなければならない3要素)

asm volatile(
"vld1.32 d0, [%0], #8 \n"  
"vst1.32 d0, [%1]" : : "r" (a), "r" (out): "d0", "r5"); 

をロードしようと「アウト」へのポインタであります整数(デバッグ用)。

4)私は右にシフトする必要がありますが、動作するようには思えない配列から値をロードした後:

vshr.u32 d0, d0, #24  // C code: x >> 24; 

5.)のみ負荷1バイトのことが可能ですネオンレジスタに入れて、シフト/マスクするだけで1つのバイトだけを取得する必要はありません。

6)私は、インラインアセンブラを使用する必要があるが、私は最後の行が何のためにあるのかわからない:あなたはコード例と何かいいNEON参照を知っています

input list : output list : what is this for? 

7)?

プログラムはSamsung Galaxy S2、cortex-A9プロセッサーで実行する必要があります。助けてくれてありがとう。

----------------何で編集-------------------

見つけた:それは常にあなたがネオンの一部は、アームレジスタへ転送する「VMOV」命令を使用することができます

  • フルレジスタ(64 - )をロードします

    1. オフセットはアームレジスタ内にあり、のメモリアクセスの後に ベースアドレスに追加されます。
    2. 「clobbered reg list」です。使用されているすべてのレジスタと入力リストまたは出力リストのいずれにも は記載されていません。
  • +0

    2.コンテンツをSIMDレジスタからARMレジスタに移動するとパイプラインが完全にフラッシュされ、約14サイクルのコストがかかります。避けてください。 –

    答えて

    10

    私はあなたの質問のほとんどに答えることができます(更新は:問題を「レーン」明確化)

    1)NEON命令のみ全体のレジスタをロードして保存することができます(64ビット、128ビット)時メモリとの間で通信を行います。単一のレーンをARMレジスタとの間で移動できるようにするMOV命令バリアントがあります。

    2)NEON MOV命令を使用して1つのレーンに影響を与えることができます。あまりにも多くの単一要素操作を実行すると、パフォーマンスが低下します。 NEON命令は、ベクトル(浮動小数点/整数のグループ)に対して並列演算を実行することにより、アプリケーションのパフォーマンスを向上させます。

    3)ARMアセンブリ言語の即値オフセットは、要素/レジスタではなくバイトです。 NEON命令は、即値ではなくレジスタでポストインクリメントを可能にします。通常のARM命令では、ポストインクリメントが8になるとソースポインタに8(バイト)が追加されます。

    4)NEONのシフトは、ベクトルのすべての要素に影響します。 vshr.u32を使用する24ビットのシフト権は、32ビットの符号なしロングを24ビットシフトし、シフトアウトされるビットを捨てます。

    5)NEON命令は、単一の要素を通常のARMレジスタに出し入れすることができますが、メモリからのロードまたはストアを直接「レーン」に入れることはできません。

    6)?

    7)ここから開始http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/ ARMサイトでは、NEONのチュートリアルがあります。

    +2

    1と5について:NEONレジスタに単一の要素をロードして格納することができます。 NEONレジスタの後に要素インデックスを[]で指定するだけです。同じ表記法を使用して、ベクトルに別のベクトルからの単一の要素を乗算することができます。 – Leo

    +2

    ポストインクリメントを除いて全く正しい。 NEONを使用してポストインクリメントとして即値を追加することはできません。レジスタARMレジスタを使用してこれを実行したり、使用することができます。読み込まれたデータのサイズだけインクリメントされます。 – webshaker

    0

    6)Clobberedレジスタ。

    asm(code : output operand list : input operand list : clobber list); 
    

    あなたはオペランドとして渡されていなかったレジスタを、使用している場合は、このことについて コンパイラに通知する必要があります。次のコードは、値を4の倍数に調整します。 はr3をスクラッチレジスタとして使用し、 clobberリストでr3を指定することによってコンパイラにこれを知らせる。さらに、CPUステータスフラグはands命令によって変更されます。 疑似レジスタccをクローバーリストに追加すると、コンパイラは この変更についても通知します。

    asm (
    "ands R3, %1, #3" 
    "eor %0, %0, r3" 
    : "=r"(len) 
    : "0"(len) 
    : "cc", "r3" 
    ); 
    
    関連する問題