5

x86 / SIMDアセンブリでは、変換する必要のあるグラフィックイメージの4つの32ビットピクセルをXMMレジスタに入力しました。ただし、ピクセルは10ビットパックRGB形式であるため、次の形式で32ビットで存在します。

[  red   ][  green ][  blue  ][]
RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB00

最後の2ビットはパディングビットであり、未使用です。

これらのピクセルに別の値を掛ける必要がありますが、値をマスクする必要があるため、たとえば赤いピクセルにのみ影響します。この値は一定であるため、ハードコーディングできます。値が0.1234だとしましょう。これを適切なマスキングを使用して別のXMMレジスタに入れて、各32ビットセグメントの赤の部分にのみ影響を与えるにはどうすればよいですか?

グラフィカルに示されているように、私は次のようなことをしたいと思います。

XMM0 (first 32 bit segment):
[ 0.1234 ][  1.0   ][  1.0   ][]

*

XMM1 (first 32 bit segment):
RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB00

その結果、XMM0とXMM1の積になります。もちろん、この32ビットセグメントはXMMレジスタ全体で複製されます。ここで最初の32ビットを指定したので、わかります。

4

2 に答える 2

3

本当に赤い部分だけに影響を与えたい場合は、赤と緑の一部に定数を掛けて (レジスタを 16 ビット ショートのコレクションとして扱う) トリックを思いつくことができるかもしれません。古い緑と青の新しい赤い部分。

すべての色を操作する場合のより良い戦略は、シフトとシャッフルの組み合わせを使用して、その形式をサポートされている xmm レジスタ形式 (16 ビットまたは 32 ビットの short または float など) に展開することです (場合によっては、 float) 操作。次に、すべての計算を行ってから、元に戻します。

何らかの値を再利用している場合 (たとえば、フィルター カーネルを計算している場合)、float で作業している場合は、展開して一度float に変換してから、その値を何度も再利用すると、はるかに高速になります。オーバー。行全体を操作して行全体を再パックする前に、行全体を 32 ビット float にアンパックするループを作成する必要がある場合でも。

于 2013-02-18T19:35:55.380 に答える
2

浮動小数点を使用して値を乗算すると仮定すると、R / G / B値を、値ごとにXMMレジスタの個々の浮動小数点セクション(1023.0で除算)にアンパックします。

また、実際には、4つのR、4つのG、および4つのB値を準備し、別のXMMレジスタの各色値に対して同じ乗数を持つ値を作成し、それを乗算する方が、保持するよりも簡単であることがわかります。 1つのレジスタ内のR、G、およびB。明らかに、これにはループの展開が少し必要になりますが、とにかくパフォーマンスがかなり向上する傾向があります。

于 2013-02-18T20:49:09.447 に答える