short
(またはint
)の出力先配列に追加する必要がある非常に長いバイト配列があります。 このようなSSE命令は存在しますか?またはそれらのセット?SSE命令:Byte + Short
6
A
答えて
6
8ビット値の各ベクトルを16ビット値の2つのベクトルにアンパックしてそれらを加算する必要があります。
__m128i v = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
__m128i vl = _mm_unpacklo_epi8(v, _mm_set1_epi8(0)); // vl = { 7, 6, 5, 4, 3, 2, 1, 0 }
__m128i vh = _mm_unpackhi_epi8(v, _mm_set1_epi8(0)); // vh = { 15, 14, 13, 12, 11, 10, 9, 8 }
v
は16×8ビット値のベクトルとvl
であり、vh
は8×16ビット値の二アンパックベクトルです。
私は8ビット値が符号なしであると仮定しているので、16ビットにアンパックすると上位バイトは0(つまり符号拡張なし)に設定されます。
これらのベクトルの多くを合計して32ビットの結果を得たい場合は、_mm_madd_epi16
と1を使用すると便利です。
__m128i vsuml = _mm_set1_epi32(0);
__m128i vsumh = _mm_set1_epi32(0);
__m128i vsum;
int sum;
for (int i = 0; i < N; i += 16)
{
__m128i v = _mm_load_si128(&x[i]);
__m128i vl = _mm_unpacklo_epi8(v, _mm_set1_epi8(0));
__m128i vh = _mm_unpackhi_epi8(v, _mm_set1_epi8(0));
vsuml = _mm_add_epi32(vsuml, _mm_madd_epi16(vl, _mm_set1_epi16(1)));
vsumh = _mm_add_epi32(vsumh, _mm_madd_epi16(vh, _mm_set1_epi16(1)));
}
// do horizontal sum of 4 partial sums and store in scalar int
vsum = _mm_add_epi32(vsuml, vsumh);
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 8));
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 4));
sum = _mm_cvtsi128_si32(vsum);
0
ゼロ拡張ではなく、バイトベクトルを符号拡張する必要がある場合は、pmovsxbw
(_mm_cvtepi8_epi16
)を使用します。 unpack hi/lo命令とは異なり、srcレジスタの下半分/四分の一/ 8分の1からpmovsxしかできません。
intrinsicsがこれを本当に不器用にしても、メモリから直接pmovsxを実行できます。シャッフルスループットはほとんどのCPUの負荷スループットよりも制限されているので、1ロード+ 3シャッフルよりも2ロード+ pmovsxを実行する方が望ましいでしょう。
関連する問題
- 1. AltiVecへのMMX/SSE命令の移植
- 2. SSEプリフェッチ命令サイズを決定する方法は?
- 3. SSE命令セットが有効になっていません
- 4. SSE命令はどのように使用できますか?
- 5. インラインアセンブリを使用しないgccでのSSE命令の使用
- 6. SSE命令によるクローン作成 - XMMレジスタの拡張
- 7. 命令レベルプロファイリング:命令ポインタの意味?
- 8. byte []をshort []に変換する
- 9. DelphiはすべてのMMX/SSE命令をサポートしていますか?
- 10. アレイのすべての要素を追加するためのSSE命令
- 11. デコード68k命令
- 12. ドッカーファイルONBUILD命令
- 13. LEA命令?
- 14. MIPSシフト命令
- 15. ストリング命令
- 16. gccインラインsimdアセンブリエラー:ショートタイプmovdqu命令
- 17. WCF命令的バインド
- 18. アームサムモード4バイト命令
- 19. ASP.Net実行命令
- 20. 命令ポインタとプログラムカウンタ?
- 21. アセンブリMIPS TAl命令
- 22. MIPS分岐命令
- 23. MIPSの 'align'命令
- 24. アセンブリJZ命令CMP
- 25. ARMのプリフェッチ命令
- 26. SIGILL(BL命令の)
- 27. アセンブラSTRB命令は
- 28. デコード命令のパターン
- 29. WHERE NOT SQL命令
- 30. スカラのバイトコードで不要なロード命令とストア命令
私の知らないことがありますが、これは間違いないと思いますか?このvsum = _mm_madd_epi16(vh、_mm_set1_epi16(1));以前のvsumの値が消去されます。 – Alexandros
@Alexandros:あなたは正しいと思います。私はこの答えを書いたときに急いでいたに違いないと思います。すぐにコードを修正しますが、私は旅行しています。プレゼント。 –
ありがとうポール、急いではありません。あなたは過去に私をたくさん助けてくれました。いつでも可能な限り修正してください。良い旅を!! – Alexandros