Intrinsics for CPUID like informations?
Asked Answered
C

5

17

Considering that I'm coding in C++, if possible, I would like to use an Intrinsics-like solution to read useful informations about the hardware, my concerns/considerations are:

  • I don't know assembly that well, it will be a considerable investment just to get this kind of informations ( altough it looks like CPU it's just about flipping values and reading registers. )
  • there at least 2 popular syntax for asm ( Intel and AT&T ), so it's fragmented
  • strangely enough Intrinsics are more popular and supported than asm code this days
  • not all the the compilers that are in my radar right now support inline asm, MSVC 64 bit is one; I'm afraid that I will find other similar flaws while digging more into the feature sets of the different compilers that I have to use.
  • considering the trand I think that is more productive for me to bet on Intrinsics, it should be also way more easy than any asm code.

And the last question that I have to answer to is: how to do a similar thing with intrinsics ? Because I haven't found nothing other than CPUID opcodes to get this kind of informations at all.

Caracara answered 20/7, 2013 at 3:40 Comment(1)
Clang has an integrated assembler, and its support for Intel style assembly is spotty at times. It can't generate a simple negate (neg) under Intel style.Leinster
C
14

After some digging I have found a useful built-in functions that is gcc specific.

The only problem is that this kind of functions are really limited ( basically you have only 2 functions, 1 for the CPU "name" and 1 for the set of registers )

an example is

#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.

Caracara answered 20/7, 2013 at 5:43 Comment(1)
From the question: "not all the the compilers ... support inline asm, MSVC 64 bit is one". The provided code certainly does not work on Microsoft compilers. You should avoid accepting your answer until you have both GCC and MS solutions.Leinster
T
8

Gcc includes a cpuid interface:

http://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/i386/cpuid.h

These don't seem to be well documented, but example usage can be found here:

http://gcc.gnu.org/git/?p=gcc.git;a=blob_plain;f=gcc/config/i386/driver-i386.c

Note that you must use __cpuid_count() and not __cpuid() when the initial value of ecx matters, such as with avx/avx2 detection.

As user2485710 pointed out, gcc can do all the cpu feature detection work for you. As of gcc 4.8.1, the full list of features supported by __builtin_cpu_supports() is: cmov, mmx, popcnt, sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx and avx2.

Transposition answered 21/7, 2013 at 4:33 Comment(0)
S
7

Intrinsics such as this are also generally compiler specific.

MS VC++ has a __cpuid (and a __cpuidex) to generate a CPUID op code.

At least as far as I know, gcc/g++ doesn't provide an equivalent to that though. Inline assembly seems to be the only option available.

Seif answered 20/7, 2013 at 4:34 Comment(1)
gcc provides a cpuid.h header which provides a __cpuid macro (defined differently than MSVC's, mind you) as well as a __get_cpuid function.Disbud
J
7

For great-grandchildren, this is how to obtain CPU vendor name with GCC, tested on Win7 x64

    #include <cpuid.h>
    ...
    int eax, ebx, ecx, edx;
    char vendor[13];
    __cpuid(0, eax, ebx, ecx, edx);
    memcpy(vendor, &ebx, 4);
    memcpy(vendor + 4, &edx, 4);
    memcpy(vendor + 8, &ecx, 4);
    vendor[12] = '\0';
    printf("CPU: %s\n", vendor);
Joost answered 18/11, 2018 at 18:2 Comment(1)
I hope my great-gandfather was as cool as you. Thanks.Rowney
L
6

For x86/x64, Intel provides an intrinsic called _may_i_use_cpu_feature. You can find it under the General Support category of the Intel Intrinsics Guide page. Below is a rip of Intel's documentation.

GCC supposedly follows Intel with respect to intrinsics, so it should be available under GCC. Its not clear to me if Microsoft provides it because they provide most (but not all) Intel intrinsics.

I'm not aware of anything for ARM. As far as I know, there is no __builtin_cpu_supports("neon"), __builtin_cpu_supports("crc32"), __builtin_cpu_supports("aes"), __builtin_cpu_supports("pmull"), __builtin_cpu_supports("sha"), etc under ARM. For ARM you have to perform CPU feature probing.


Synopsis

int _may_i_use_cpu_feature (unsigned __int64 a)

#include "immintrin.h"

Description

Dynamically query the processor to determine if the processor-specific feature(s) specified
in a are available, and return true or false (1 or 0) if the set of features is
available. Multiple features may be OR'd together. This intrinsic does not check the
processor vendor. See the valid feature flags below:

Operation

    _FEATURE_GENERIC_IA32
    _FEATURE_FPU
    _FEATURE_CMOV
    _FEATURE_MMX
    _FEATURE_FXSAVE
    _FEATURE_SSE
    _FEATURE_SSE2
    _FEATURE_SSE3
    _FEATURE_SSSE3
    _FEATURE_SSE4_1
    _FEATURE_SSE4_2
    _FEATURE_MOVBE
    _FEATURE_POPCNT
    _FEATURE_PCLMULQDQ
    _FEATURE_AES
    _FEATURE_F16C
    _FEATURE_AVX
    _FEATURE_RDRND
    _FEATURE_FMA
    _FEATURE_BMI
    _FEATURE_LZCNT
    _FEATURE_HLE
    _FEATURE_RTM
    _FEATURE_AVX2
    _FEATURE_KNCNI
    _FEATURE_AVX512F
    _FEATURE_ADX
    _FEATURE_RDSEED
    _FEATURE_AVX512ER
    _FEATURE_AVX512PF
    _FEATURE_AVX512CD
    _FEATURE_SHA
    _FEATURE_MPX
Leinster answered 25/7, 2017 at 18:19 Comment(1)
It seems the _may_i_use_cpu_feature intrinsic is not listed here learn.microsoft.com/en-us/cpp/intrinsics/… unfortunately. :/ too bad.Witchcraft

© 2022 - 2024 — McMap. All rights reserved.