5

クロスプラットフォーム C 用に、ウェブカメラ画像に対してさまざまなことを行うためのライブラリをプログラミングしています。すべての操作はピクセル単位で高度に並列化可能です。たとえば、ビット マスクの適用、色値と定数の乗算などです。したがって、SSE/SSE2 組み込み関数を使用することでパフォーマンスを向上できると思います。

ただし、データ形式に問題があります。私の Web カメラ ライブラリは、ABGR または BGR 形式の 24 ビットまたは 32 ビットのバイト ピクセルを含むバッファーへのポインター (void*) として Web カメラ フレームを提供します。ptr++ などが正しく動作するように、これらを char* にキャストしています。ただし、すべての SSE/SSE2 操作では、__m128 または __m64 データ型で 4 つの整数または 4 つの浮動小数点数が必要です。これを行うと (バッファから文字 r、g、および b に色の値を読み取ったと仮定して):

float pixel[] = {(float)r, (float)g, {float)b, 0.0f};

次に、定数でいっぱいの別の float 配列をロードします

float 定数[] = {0.299, 0.587, 0.114, 0.0f};

両方の float ポインターを __m128 にキャストし、__mm_mul_ps 組み込み関数を使用して r * 0.299、g * 0.587 などを実行します。すべてのシャッフルに時間がかかるため、全体的なパフォーマンスは向上しません。

これらのバイトピクセル値をSSEレジスタにすばやく効率的にロードして、実際にそれらを操作することでパフォーマンスを向上させる方法について誰か提案がありますか?

4

3 に答える 3

1

MMXを使用する場合は...

MMXは、各レジスタを8、8ビット値として扱うことができる64ビットレジスタの束を提供します。

使用している8ビット値のように。

ここに良い入門書があります。

于 2009-12-22T05:53:49.010 に答える
1

パフォーマンスのボトルネックは、フロートへのキャストに起因する可能性があると思います。これは、かなり高価な操作です。

私がよく覚えている場合、そのキャストはほとんどのアーキテクチャで約50クロックサイクルです...そして、FP乗算にかかる可能性のある最悪のケースを考えると、たとえば、パイプラインでオーバーラップせずにそれぞれ約4クロック、それらすべてを実行します1サイクルで並行して実行すると、最大で15サイクル節約できますが、それでも利益はありません。

Shmoopty が言ったように MMX でストリーミングする場合は、常に同じ数値形式 (この場合は整数) で作業することをお勧めします。

于 2009-12-22T15:52:32.523 に答える
0

まず、コピー元のデータ (そのポインターによって指されていると思いvoid*ます) は、最適なパフォーマンスを得るためにメモリで整列する必要があります。そうでない場合は、メモリで整列されたバッファにコピーします。

第二に、データをメモリ アライメント バッファに移動した後でも SSE2 を使用できます。これは非常に簡単です。ここでコードを使用しても組み込みの問題は発生しませんでした (ただし、アセンブリには問題がありました。詳しくはこちらを参照してください)。

これが役立つことを願っています-私も画像をunsigned char操作してメインメモリに保存し、それらをSSE2レジスタにコピーしました(R、G、またはBが0〜255で変化するため意味がありました)-しかし、アセンブリコードを使用したのでより簡単に感じました。

しかし、クロスプラットフォームにしたい場合は、組み込み関数を使用する方がクリーンになると思います。

幸運を!

于 2009-12-22T15:19:29.723 に答える