2012-01-31 19 views
17

私のプログラムで行う一般的な操作は、スカラー(V * s [1,2,3,4] * 2 == [2,4、 6,8])。これを行うためのSSE(またはAVX)命令がありますか?ベクトルのすべての位置に最初にスカラーをロードすること以外は(例えば_mm_set_ps(2,2,2,2))、? ...私のようなものを探していますSSE(SIMD):スカラーによるベクトルの乗算

__m128 _scalar = _mm_set_ps(s,s,s,s); 
__m128 _result = _mm_mul_ps(_vector, _scalar); 

私は何をしたいん任意の単一の命令を知らない

__m128 _result = _mm_scale_ps(_vector, s); 

答えて

13

const __m128 scalar = _mm_set1_ps(s); 
__m128 result = _mm_mul_ps(vector, scalar); 

しかし、このようなスカラー定数は任意のループの外に、一度初期化されるのみ必要があるの、そのパフォーマンスコストは無関係でなければならない。

いつものように、コンパイラが生成するコードを見て、まともなプロファイラの下でコードを実行して、ホットスポットが実際にどこにあるかを調べるべきです。

0

これは私が今何をすべきかです。セット操作は本当にボトルネックですか?大きなベクトルに同じ定数を乗算する場合、定数の4つのコピーでXMM/YMMレジスタを埋めるのに要する時間は、全体の時間のうちごくわずかです。

単純な最適化として、例のように定数が2の場合、定数を必要とせずに、乗算をadd命令で置き換えることができます。コンパイラによっては、あなたが少し_mm_set1_psを使用してコード生成を改善することができるかもしれ

4

ベクトルをスカラーで乗算する命令はありません。ただし、ベクトルレジスタのすべての位置に同じスカラー値をロードするための命令があります。

AVX命令セットは、同一の浮動/ダブル値に登録SSEおよびAVXを移入するため_mm_broadcast_ss/_mm256_broadcast_ss/_mm256_broadcast_sd組み込み関数を提供します。

SSE3命令セットでは、SSEレジスタに同じdouble値を設定する組み込み関数_mm_loaddup_pdがあります。 SSEの他のバージョンでは

は、典型的には、最良のオプションは_mm_load_ss/_mm_load_sdを使用してスカラー値をロードし_mm_shuffle_ps/_mm_unpacklo_pdとベクトルレジスタのすべての要素にコピーすることです。