Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dectecting CPU feature support (Eg sse2, fma4 etc)

I have some code that depends on CPU and OS support for various CPU features.

In particular I need to check for various SIMD instruction set support. Namely sse2, avx, avx2, fma4, and neon. (neon being the ARM SIMD feature. I'm less interested in that; given less ARM end-users.)

What I am doing right now is:

function cpu_flags()
    if is_linux()
        cpuinfo = readstring(`cat /proc/cpuinfo`);
        cpu_flag_string = match(r"flags\t\t: (.*)", cpuinfo).captures[1]
    elseif is_apple()
        sysinfo = readstring(`sysctl -a`);
        cpu_flag_string = match(r"machdep.cpu.features: (.*)", cpuinfo).captures[1]
    else
        @assert is_windows()
        warn("CPU Feature detection does not work on windows.")
        cpu_flag_string = ""
    end
    split(lowercase(cpu_flag_string))
end

This has two downsides:

  1. It doesn't work on windows
  2. I'm just not sure it is correct; it it? Or does it screw up, if for example the OS has a feature disabled, but physically the CPU supports it?

So my questions is:

  1. How can I make this work on windows.
  2. Is this correct, or even a OK way to go about getting this information?

This is part of a build script (with BinDeps.jl); so I need a solution that doesn't involve opening a GUI. And ideally one that doesn't add a 3rd party dependency. Extracting the information from GCC somehow would work, since I already require GCC to compile some shared libraries. (choosing which libraries, is what this code to detect the instruction set is for)

like image 988
Lyndon White Avatar asked Aug 28 '16 14:08

Lyndon White


1 Answers

I'm just not sure it is correct; it it? Or does it screw up, if for example the OS has a feature disabled, but physically the CPU supports it?

I don't think that the OS has any say in disabling vector instructions; I've seen the BIOS being able to disable stuff (in particular, the virtualization extensions), but in that case you won't find them even in /proc/cpuinfo - that's kind of its point :-) .

Extracting the information from GCC somehow would work, since I already require GCC to compile some shared libraries

If you always have gcc (MinGW on Windows) you can use __builtin_cpu_supports:

#include <stdio.h>

int main()
{
    if (__builtin_cpu_supports("mmx")) {
        printf("\nI got MMX !\n");
    } else
        printf("\nWhat ? MMX ? What is that ?\n");
    return (0);
}

and apparently this built-in functions work under mingw-w64 too.

AFAIK it uses the CPUID instruction to extract the relevant information (so it should reflect quite well the environment your code will run in).

(from https://stackoverflow.com/a/17759098/214671)

like image 59
Matteo Italia Avatar answered Nov 11 '22 17:11

Matteo Italia