質問

AVX Intrinsicsを使用して、VC ++でFeed Forward Netを作成しています。 C#でPinvokeを介してこのコードを呼び出しています。 function exp()を含む大きなループを計算する関数を呼び出すときの私のパフォーマンスは、160mのループサイズで〜1000msです。私が電話するとすぐに どれか AVX Intrinsicsを使用し、その後EXP()を使用する関数は、同じ操作でパフォーマンスが約8000msに低下します。 Exp()を計算する関数は標準Cであり、AVX内シックを使用する呼び出しは、処理されるデータに関して完全に無関係である可能性があることに注意してください。実行時にどこかで何らかの旗がつまずかれています。

言い換えると、

A(); // 1000ms calculates 160M exp() 
B(); // completely unrelated but contains AVX
A(); // 8000ms

または、不思議なことに、

C(); // contains 128 bit SSE SIMD expressions
A(); // 1000ms

私は、ここでどのようなメカニズムが起こっているのか、またはソルンを追求する方法について迷っています。私はIntel 2500K CPU Win 7を使用しています。Vsのエクスプレスバージョン

ありがとう。

役に立ちましたか?

解決

AVX256命令を使用すると、「AVX上部状態」が「汚い」になり、その後SSE命令(XMMレジスタで実行されるスカラーフローティングポイントを含む)を使用すると大きな失速が得られます。これは、Intel Optimization Manualに文書化されています。 無料でダウンロードしてください (そして、あなたがこの種の仕事をしている場合、必見です):

AVX命令は常にYMMレジスタの上部ビットを変更し、SSE命令は上部ビットを変更しません。ハードウェアの観点から見ると、YMMレジスタコレクションの上部ビットは、3つの状態のいずれかにあると考えることができます。

•クリーン:YMMの上部ビットはすべてゼロです。これは、プロセッサがリセットから始まる状態です。

•Xsave領域に変更および保存されたYMMレジスタの上部ビットの内容は、Xsave領域の保存されたデータを一致させます。これは、XSave/Xrstorが実行された後に発生します。

•修正および救済されていない:1つのAVX命令(256ビットまたは128ビットのいずれか)の実行により、宛先YMMの上部ビットが変更されます。

AVX/SSE遷移ペナルティは、プロセッサの状態が「変更され、救われていない」ときはいつでも適用されます。 Vzeroupperを使用して、プロセッサ状態を移動して「クリーン」し、移行ペナルティを回避します。

あなたのルーチン B( ) YMM状態を汚すので、SSEコード A( ) 屋台。挿入します VZEROUPPER 間の指示 BA 問題を避けるため。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top