1

現時点では、ユニオンを介してフロート値にアクセスしています

typedef union
{
  float v[4];
  _mm128 m;
}SSEFloat;

しかし、このリンクでは、パフォーマンスが失われていると聞きました。GCC 4 でパフォーマンスが低下することはありますか? フロートを揃える必要がありますか? ユニオンでも?または、このような値を設定するのは正しいですか

SSEFloat a;
float tmp = 10.0;
a.m = _mm_load1_ps( &tmp );

現時点では、Intel SSE Intrinsic Documentation も見つかりませんでした :( 「小さな」リストはありますか - 速度の最適化について知っておくべきことは何ですか?

4

2 に答える 2

2

コンパイラは、コードが正しく実行されることを保証しますが、正確さのためにパフォーマンスを犠牲にする可能性があります。共用体は実際には 4 項目の float ベクトルの個々の要素にアクセスするための構文上の利便性を追加するだけであり、_mm128 オブジェクトは (実際にはそうでなくても概念的に) レジスターに格納されているため、_mm128 オブジェクトを直接使用して使用することをお勧めします。_mm_store_psおよび_mm_load_psファミリの API を使用して、オブジェクトの内外にデータを移動します。

あなたが提供したリンクのコメントは、特に _mm128s を使用して、コンパイラがユニオン周辺で不十分な最適化を実行できることを示唆しています。これを確認したい場合は、結合ありとなしの両方で実験を行う必要があります。Linux で高精度の時間測定を行うには、pthread_getcpuclockidおよびclock_gettime API をお勧めします。できれば結果を投稿してください!

一般に、最高のパフォーマンスを得るには、コンパイラーにとって物事をできるだけ簡単かつシンプルにします。これは、_mm128 のような高性能のものを共用体のような複雑な構造から除外し、代わりにスタックまたは明示的に割り当てられたメモリで宣言することを意味します。

于 2013-04-15T22:27:54.293 に答える
0

共用体で float を使用する場合、コンパイラはおそらくそれらにアクセスするための非 sse コードを出力し、パフォーマンス ヒットになります。それは本当にオブジェクトの使用法に依存します。ラッパー構造体の前に _MM_ALIGN16 (__declspec(align(16)) を追加し、new および delete 演算子をオーバーライドできます (C++ をコーディングしている場合)。この質問を確認してください: SSE、組み込み関数、アライメント

于 2013-04-23T07:36:37.240 に答える