私はSIMDの組み込み関数の初心者ですから、あらかじめ忍耐強くお礼を申し上げます。私は符号なしバイトの絶対差分比較を含むアプリケーションを持っています(私はグレースケール画像で作業しています)。SSE2 __m128i構造体からバイトを抽出する方法は?
私はAVX、より近代的なSSEバージョンなどを試しましたが、最終的にはSSE2で十分と思われ、個々のバイトを最大限サポートしています。間違っていると私を修正してください。
私は2つの質問があります:まず、128ビットレジスタをロードする正しい方法は何ですか?私は、私は128の倍数に整列ロード組み込み関数のデータを渡すことになってると思いますが、このような2次元配列のコードでその仕事になります。
greys = aligned_alloc(16, xres * sizeof(int8_t*));
for (uint32_t x = 0; x < xres; x++)
{
greys[x] = aligned_alloc(16, yres * sizeof(int8_t*));
}
は、(上記のコードはXRESとyresが同じであると仮定し、としています2のべき乗)。これはメモリ内の線形で途切れのないブロックになりますか?私はループして、SSE2のロードイントリンシクスにアドレスを渡し続けます(128をインクリメントする)ことができますか?それとも、このような2D配列のために何か別の必要性がありますか?
私のすべてのベクトル処理が完了したら、__m128i
から変更されたバイトをどのように抽出するのですか?インテルイントリンシックスガイドを見て、ベクトル型をスカラー型に変換する手順はまれです。私が見つけた最も近いのは_mm_movemask_epi8 (__m128i a)
ですが、どうやって使うのか分かりません。
ああ、3分の1質問 - 私は_mm_load_si128
が符号付きバイトだけを読み込むと仮定しましたか?そして、私は他のバイトローディング関数を見つけることができませんでした。だから、それぞれから128を引いて、後でそれを説明すると思いますか?
私はこれらがSIMDの専門家のための基本的な質問であることを知っていますが、私はこの1つが私のような初心者に役立つことを願っています。アプリケーションへの私の全体的なアプローチが間違っていると思うのであれば、私はもっと近代的なSIMDエクステンションを使う方が良いと思っています。私は謙虚に私がアセンブリで働いたことはないと警告したいと思います。そして、この手の込んだすべてのものは、私を助けるためには多くの説明が必要です。
それにもかかわらず、私は利用可能なすべての説明に感謝しています。
違いがある場合:私は、低電力i7 Skylakeアーキテクチャをターゲットにしています。しかし、アプリケーションをずっと古いマシンで実行させるのもいいでしょう(それゆえSSE2)。最初
他のオプションは、コンパイラが最初にベクトル化するかどうかを確認し、次にコンパイラが実行できる処理がさらに必要な場合は、後でイントリンシックを追加します。理想的には私たちはすべてバニラコードを使用し、コンパイラライターが最適化するために設定したものであれば、コンパイラはSSE、AXVなどをサポートします。 – Holmz
@Peter Cordez - 残念ながら、私は16バイトのベクトルにバイトをロードする方法を見つけることさえできません。 load/storeコマンドはすべて、アドレスを含む結果と引数の両方のベクトルを使用しているようです!私の直感は、私はバイト配列からアドレスを(ロード引数として)提供していましたが、ロード組み込み関数はベクトルを引数として必要とするため不可能です。そして、私は、通常の、スカラーの64ビットアドレスから(アドレス)ベクトルを返す組み込み関数を見つけることができません! – sacheie
@sacheie:そうですね、整数の場合は、_mm_loadu_si128((const __m128i *)my_int_pointer) 'を使う必要があります。タグwikiからリンクされているチュートリアルのいずれかを見れば、これを見つけたでしょう。 –