どのように私は、ARMネオン組み込み関数を使用してベクトルデータリオーダーのですか?
-
26-09-2019 - |
質問
これは、具体的にはARMネオンSIMD符号化に関連しています。私は、ビデオデコーダ内の特定のモジュールのARMネオンinstrinsicsを使用しています。次のように私は、ベクトル化データを持っています:
たとえば、Q0 - - サイズ128ビットであるは、4つの32ビット・ネオン・レジスタの要素があります。
3B 3A 1B 1A
サイズ128ビットである他のネオンレジスタ言うQ1に別の4つの32ビット要素があります。
3D 3C 1D 1C
私は以下に示すように、最終的なデータが順番になりたいます:
1D 1C 1B 1A
3D 3C 3B 3A
どのようなネオンinstrinsicsが所望のデータの順序を達成することができますか?
解決
どのようにこのようなものについて:
int32x4_t q0, q1;
/* split into 64 bit vectors */
int32x2_t q0_hi = vget_high_s32 (q0);
int32x2_t q1_hi = vget_high_s32 (q1);
int32x2_t q0_lo = vget_low_s32 (q0);
int32x2_t q1_lo = vget_low_s32 (q1);
/* recombine into 128 bit vectors */
q0 = vcombine_s32 (q0_lo, q1_lo);
q1 = vcombine_s32 (q0_hi, q1_hi);
vget_highとvget_lowはちょうど2つの64ビットのDレジスタとして128ビットQレジスタを再解釈するので理論的には、これはちょうど2つの移動命令にコンパイルすべきです。 1つのまたは2の移動(レジスタ割り当てに依存します)にだけコンパイル大藤vcombine。
ああ - と出力の整数の順序の周りに正確に間違った方法である可能性があります。もしそうなら、単にvcombine_s32に引数をスワップします。
他のヒント
各Qレジスタは、例えば、Q0の低い部分がd0と高い部d1であり、2つのDレジスタで構成されてください。この操作はちょうどD0とD3スワッピングされるように実際には、(またはD1およびD2を、それはあなたのデータのプレゼンテーションから完全には明らかではありません)。一つの命令でそれを行うためのスワップ命令もあります!
。免責事項:これは組み込み関数を使用して行うことができなかった場合、私は驚かれると思いますけれども。
私は、ネオン組み込み関数(アセンブリで、私は直接コード)を知りませんそれはあなたがこのために(例えばVTRN
)vtrnq_u32
命令を使用することができるはずのように見えます。
ピエールは正しいです。
VSWP D0、D3
行います。
@Pierre: 私は数ヶ月前にあなたのブログにNEONについての記事をお読みください。手最適化されたアセンブリコード、ARM NEONとの両方を書く - 私は愉快に私のような誰かがあったことに驚きました。 ニースはあなたを見てます。