2016-09-09 2 views
0

平均4つの隣接画素に二度隣接を追加すること、およびD3 Iは、平均したい4つの隣接:ARMネオン:私は4つのレーンD0、D1、D2を有する

d0[0] = (d0[0] + d0[1] + d0[2] + d0[3])/4 
d0[1] = (d0[4] + d0[5] + d0[6] + d0[7])/4 
d0[2] = (d1[0] + d1[1] + d1[2] + d1[3])/4 
... 

は、以下ネオンコードが正しいですか?

vpaddl.u8 d0, d0 
vpaddl.u8 d1, d1 

vpaddl.u8 d2, d2 
vpaddl.u8 d3, d3 

vpadd.u16 d0, d0, d2 
vshrn.u16 d0, q0, #2 

「はい」の場合、それを行う方法はありますか?

EDIT 1

上記のコードが正しくありませんでした。私は以下を思いついた:

vpaddl.u8 d0, d0 
vpaddl.u8 d1, d1 
vpaddl.u8 d2, d2 
vpaddl.u8 d3, d3 
vuzp.u16 q0, q1 
vadd.u16 q0, q0, q1 
vshrn.u16 d0, q0, #2 

これは働いています。これは「Notlikethat」の回答の2番目の提案と非常によく似ていますが、あまり最適化されていません。

+1

このデータには他にどのような操作を行っていますか?可能であれば、水平操作は避けるのが最善であるため、データの配置が最初とは異なる場合は_best_オプションになります.d0-d3の隣接データを 'vld4'でインターリーブすることができれば、通常の並列操作を意図したとおりに行う。 – Notlikethat

+0

私は同意しますが、残念ながら、いいえ、私はこの場合にvld4を行うことはできません。データを並べ替えるためにzipやvextをやっていると思っていましたが、指示が少なくなってしまい、使用可能なレーン数が限られていました。私の質問はまだ立っていることに注意してください(!)、コードは少なくとも正しいですか? – gregoiregentil

答えて

3

公正なビットのplaying aroundの後、私は与えられた制約の下で、あなたの一般的なアプローチはおそらくあなたが得ようとしているほど良いと言います。 4つ以上のレジスタを一度に処理することができ、アルゴリズム内の他の場所でベクトルを並べ替えるコストを吸収する機会がありますが、結論は異なる可能性がありますが、実行可能なオプションは非常に限られています。

あなたは、しかし、削減のあなたの第二ラウンドでd1d3を忘れている、とvpaddとは異なり、vpaddlフォームを登録Qを持っているので、最初のラウンドは、2つの命令にまで単純化することができます。これらはこれで終わるの修正:純粋な命令数の面では

vpaddl.u8 q0, q0 
vpaddl.u8 q1, q1 
vpadd.u16 d0, d0, d1 
vpadd.u16 d1, d2, d3 
vshrn.u16 d0, q0, #2 

、それは、このように、直接2対毎の削減を蓄積し、その後、部分的転置を行うことにより、低行くことが出来です:

vuzp.16 q0, q1 
vpaddl.u8 q0, q0 
vpadal.u8 q0, q1 
vshrn.u16 d0, q0, #2 

しかしQ形式vuzpであり、実際にはであり、私は命令タイミングを見つけることができず、vpadalの累積値も無料ではないので、moより全体的に悪いまっすぐなバージョン。

+0

と「再生中」のリンクに1つそれはかなりクールなオンラインユーティリティです! – gregoiregentil

関連する問題