7

AVX組み込み関数を使用してVC++でフィードフォワードネットを作成しています。このコードは、C#のPInvokeを介して呼び出しています。関数exp()を含む大きなループを計算する関数を呼び出すときの私のパフォーマンスは、160Mのループサイズで約1000msです。AVX組み込み関数を使用する関数を呼び出し、その後exp()を使用するとすぐに、同じ操作でパフォーマンスが約8000ミリ秒に低下します。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

ここでどのようなメカニズムが起こっているのか、あるいはどのように解決策を追求するのかについて、私は迷っています。私はIntel2500Kcpu \Win7を使用しています。VSのExpressバージョン。

ありがとう。

4

1 に答える 1

10

AVX256命令を使用すると、「AVX上位状態」が「ダーティ」になり、その後SSE命令(xmmレジスタで実行されるスカラー浮動小数点を含む)を使用すると、大きなストールが発生します。これは、無料でダウンロードできるインテル最適化マニュアルに記載されています(この種の作業を行う場合は必読です)。

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

•クリーン:YMMの上位ビットはすべてゼロです。これは、プロセッサがRESETから起動したときの状態です。

•変更してXSAVE領域に保存YMMレジスタの上位ビットの内容は、XSAVE領域に保存されたデータと一致します。これは、XSAVE/XRSTORの実行後に発生します。

•変更および未保存:1つのAVX命令(256ビットまたは128ビット)を実行すると、宛先YMMの上位ビットが変更されます。

AVX / SSE遷移ペナルティは、プロセッサの状態が「変更済みおよび未保存」の場合に適用されます。VZEROUPPERを使用して、プロセッサの状態を「クリーン」に移動し、遷移ペナルティを回避します。

あなたのルーチンB( )はYMM状態を汚すので、SSEコードはA( )失速します。問題を回避するには、とVZEROUPPERの間に命令を挿入します。BA

于 2011-05-04T23:07:06.280 に答える