Search code examples
c++windowsx86intrinsicsavx

How to programmatically check if fused mul add (FMA) instruction are enabled on the CPU?


I would like to use the FMA instrinsics instructions _mm256_fmadd_pd(a, b, c), but my code has to run on different computers with or without FMA enabled. I cannot use a compile-time flag. So I would like to be able to write something like this:

__m256d a, b, c, x;
bool FMA_Enabled = CheckFMA();

if (FMA_Enabled)
{
  d = _mm256_fmadd_pd(a, b, c);
}
else
{
  x = _mm256_mul_pd(a, b);
  d = _mm256_add_pd(x, c);
}

I cannot find a way to write the function CheckFMA(). Is there a way to do this?

My OS is Windows 10 64 bits.

EDIT: The branching will actually be outside of the function. So I don't lose performance by checking the FMA support every time.


Solution

  • I used __cpuid to code my function by modifying the microsoft code. Thank you very much to all for your help.

    #include <intrin.h>
    #include <vector>
    #include <bitset>
    #include <array>
    
    bool CheckFMA()
    {
        std::array<int, 4> cpui;
        std::bitset<32> ECX;
        int nIds;
        bool fma;
    
        __cpuid(cpui.data(), 0);
        nIds = cpui[0];
    
        if (nIds < 1)
        {
            return false;
        }
    
        __cpuidex(cpui.data(), 1, 0);
        ECX = cpui[2];
    
        return ECX[12];
    }