私のC++コードはSSEを使用していますが、AVXが使用可能になったときにサポートするように改善したいと考えています。 VS2010 SP1およびAVXを搭載したCPU。
AVXを使用するには、これを含める必要があります。
#include "immintrin.h"
その後、_mm256_mul_ps
、_mm256_add_ps
などの組み込みAVX関数を使用できます。問題は、デフォルトでは、VS2010が非常にゆっくり動作し、警告を表示するコードを生成することです。
警告C4752:Intel(R)Advanced Vector Extensionsが見つかりました。/Arch:AVXの使用を検討してください
VS2010は実際にはAVX命令を使用しないようですが、代わりにそれらをエミュレートします。 /Arch:AVX
をコンパイラオプションに追加し、良い結果を得ました。ただし、このオプションは、可能な場合はどこでもAVXコマンドを使用するようコンパイラーに指示します。したがって、AVXをサポートしていないCPUでコードがクラッシュする可能性があります!
ですから、AVXコンパイラを作成してAVXコードを生成する方法ですが、AVX組み込み関数を直接指定する場合にのみ問題になります。 SSEそれが機能するために、私はSSE組み込み関数を使用し、/Arch:SSE
のようなコンパイラオプションなしでSSEコードを生成します。しかし、AVXでは何らかの理由で機能しません。
表示されている動作は、高価な状態切り替えの結果です。
Agner Fogのマニュアルの102ページを参照してください。
http://www.agner.org/optimize/microarchitecture.pdf
SSE命令とAVX命令を不適切に切り替えるたびに、非常に高い(〜70)サイクルペナルティが発生します。
_/Arch:AVX
_なしでコンパイルすると、VS2010はSSE命令を生成しますが、AVX組み込み関数がある場合は常にAVXを使用します。したがって、SSE命令とAVX命令の両方を含むコードを取得します。これらの状態切り替えペナルティが発生します。 (VS2010はこれを認識しているため、表示されている警告を発します。)
したがって、すべてSSEまたはAVXを使用する必要があります。 _/Arch:AVX
_を指定すると、すべてのAVXを使用するようコンパイラーに指示します。
複数のコードパスを作成しようとしているようです。1つはSSE用、もう1つはAVX用です。このため、SSEとAVXコードを2つの異なるコンパイル単位に分けることをお勧めします。 (1つは_/Arch:AVX
_でコンパイルされ、もう1つはコンパイルされません)次に、それらをリンクし、実行しているハードウェアに基づいて選択するディスパッチャーを作成します。
needSSEとAVXを混在させる場合は、必ず_mm256_zeroupper()
を使用してくださいまたは_mm256_zeroall()
適切に状態切り替えペナルティを回避します。