9

MSVC は何年も前から AVX/AVX2 命令をサポートしており、この msdn ブログ投稿によると、融合乗算加算 (FMA)命令を自動的に生成できます。

ただし、次の関数はいずれも FMA 命令にコンパイルされません。

float func1(float x, float y, float z)
{
    return x * y + z;
}

float func2(float x, float y, float z)
{
     return std::fma(x,y,z);
}

さらに悪いことに、std::fma は単一の FMA 命令として実装されておらず、プレーンよりもはるかに遅く実行x * y + zされます (実装が FMA 命令に依存していない場合、std::fma のパフォーマンスの低下が予想されます)。

/arch:AVX2 /O2 /Qvecフラグでコンパイルします。も試してみましたが/fp:fast、成功しませんでした。

問題は、MSVC に FMA 命令を自動的に発行させるにはどうすればよいかということです。

アップデート

#pragma fp_contract (on|off)(のように見える) 何もしない があります。

4

2 に答える 2

4

この長年の問題を解決しました。

/fp:fast結局のところ、flags/arch:AVX2および/O1(または上記の/O1) は、Visual Studio 2015 モードが 32 ビット モードで FMA 命令を発行するには不十分です。また、 「プログラム全体の最適化」を flag でオンにする必要があります/GL

次に、Visual Studio 2015 が FMA 命令vfmadd213ssを生成します。

float func1(float x, float y, float z)
{
    return x * y + z;
}

に関しては、 Microsoft Connect でバグstd::fmaを開きました。彼らは、コンパイラが組み込みとして扱わないため、FMA 命令にコンパイルされない動作を確認しました。彼らの回答によると、可能な限り最高の codegen を得るために、将来のアップデートで修正される予定です。std::fma

于 2016-04-08T15:44:55.653 に答える
3

MSVC 2015 は、スカラー操作の fma 命令を生成しますが、ベクトル操作の fma 命令は生成しません (明示的に fma 組み込み関数を使用しない限り)。

次のコードをコンパイルしました

//foo.cpp
float mul_add(float a, float b, float c) {
    return a*b + c;
}

//MSVC cannot handle vectors as function parameters so use const references
__m256 mul_addv(__m256 const &a, __m256 const &b, __m256 const &c) {
    return _mm256_add_ps(_mm256_mul_ps(a, b), c);
}

cl /c /O2 /arch:AVX2 /fp:fast /FA foo.cpp

MSVC2015で、次のアセンブリを生成しました

;mul_add
vmovaps xmm3, xmm1
vfmadd213ss xmm3, xmm0, xmm2
vmovaps xmm0, xmm3

;mul_addv
vmovups ymm0, YMMWORD PTR [rcx]
vmulps  ymm1, ymm0, YMMWORD PTR [rdx]
vaddps  ymm0, ymm1, YMMWORD PTR [r8]
于 2016-01-04T19:52:39.900 に答える