2

NEONを使用してAndroidコードを最適化しようと試み始めたところです。ただし、いくつか問題があります。主な問題は、16ビットから浮動小数点への迅速な変換を行う方法を実際に理解できないことです。

vcvt.s32.f32を使用して、複数の32ビットintを1つのSIMD命令でfloatに変換できることがわかりました。ただし、4つのS16のセットを4つのS32に変換するにはどうすればよいですか?VUZP命令と関係があると思いますが、どうしたらいいのかわかりません...

同様に、VCVT.s16.f32を使用して一度に116ビットをフロートに変換することは可能ですが、これは便利ですが、SIMDを使用して変換できないことは非常に無駄に思えます。

私は何年にもわたって多くの異なるプラットフォームでアセンブラを作成してきましたが、ARMのドキュメントは何らかの理由で完全に理解できないと感じています。

そのようなものとして、どんな助けでも大いに感謝されるでしょう。

また、NEONユニットのスループットとレイテンシの数値を取得する方法はありますか?

前もって感謝します!

4

3 に答える 3

4

16 ビット整数から 32 ビット整数への変換とともに他の計算を行う必要がない場合は、uint32x4_t = vmovl_u16 (uint16x4_t)を実行できます。

単純な加算や乗算などが変換前に実行されている場合は、 int32x4_t = vmull_u16 (int16x4_t, int16x4_t)またはint32x4_t = vaddl_u16 (int16x4_t, int16x4_t)などの単一の命令でそれらを組み合わせることができ、サイクル数を節約できます。

于 2011-10-18T12:45:59.777 に答える
2

私のコメントについて少し詳しく説明します。4 つの 16 ビット レジスタを 4 つの 32 ビット整数に「拡大」してから、4 つの 32 ビット浮動小数点数に変換する必要があります。命令セットを見ると、より高速な変換パスはないと思いますが、簡単に間違っている可能性があります。

直接的な方法はvaddl.s16、4 つのゼロの 2 番目のオペランドを使用することですが、変換のみを行う場合を除き、多くの場合、変換を前の操作と組み合わせることができます。たとえば、2 つの int16x4 レジスタを乗算する場合vmull.s16、最初に乗算して後で拡張するのではなく、32 ビット出力を直接取得するために使用できます (切り捨て動作に依存しない場合)。

于 2011-10-18T05:51:44.117 に答える
1

貴重なレジスタを 0 で初期化する vaddl 無駄なサイクルを使用するのはなぜですか?

vmovl.s16 q0、d1

次にq0を変換します

それでいい。

私の質問は:

  • それらをfloatに変換することは絶対に必要ですか? NEON は、float よりも整数演算の方がはるかに高速です。(実行とパイプラインの両方) したがって、算術命令と自動丸め/飽和オプションを組み合わせた強力なロング、ワイド、ナロー モデルのおかげで、ほとんどの場合、固定小数点演算がより適切になります。

PS : 奇妙なことに、ARM の PDF が最適だと思います。

于 2011-11-01T06:59:16.807 に答える