Intrinsics для CPUID, как информация?

Учитывая, что я пишу код на C++, если это возможно, я бы хотел использовать решение, подобное Intrinsics, для чтения полезной информации об оборудовании, поэтому я обеспокоен / обеспокоен следующим:

  • Я не очень хорошо знаю ассемблер, для получения такого рода информации потребуется немалое вложение (хотя, похоже, что ЦП просто переворачивает значения и читает регистры).
  • существует как минимум 2 популярных синтаксиса для asm ( Intel и AT&T), поэтому он фрагментирован
  • Как ни странно, в наши дни Intrinsics более популярны и поддерживаются, чем asm-код.
  • не все компиляторы, которые сейчас находятся в моем радаре, поддерживают встроенный asm, MSVC 64 bit - один; Я боюсь, что я найду другие подобные недостатки при копании в наборы функций различных компиляторов, которые я должен использовать.
  • Учитывая тренд, я думаю, что для меня более продуктивно делать ставки на Intrinsics, это также должно быть намного проще, чем в любом асм-коде.

И последний вопрос, на который я должен ответить: как сделать подобное с внутренностями? Потому что я не нашел ничего, кроме кодов операций CPUID, чтобы получить такую ​​информацию вообще.

5 ответов

Решение

После некоторых копаний я нашел полезные встроенные функции, специфичные для gcc.

Единственная проблема заключается в том, что такого рода функции действительно ограничены (в основном у вас есть только 2 функции, 1 для "имени" процессора и 1 для набора регистров).

пример

#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);
}

и, видимо, эти встроенные функции работают и под mingw-w64.

Gcc включает интерфейс cpuid:

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

Они не очень хорошо документированы, но пример использования можно найти здесь:

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

Обратите внимание, что вы должны использовать __cpuid_count() и не __cpuid() когда начальное значение ecx имеет значение, например, при обнаружении avx/avx2.

Как указал user2485710, gcc может выполнить всю работу по обнаружению функций процессора за вас. Начиная с gcc 4.8.1, полный список функций, поддерживаемых __builtin_cpu_supports(): cmov, mmx, popcnt, sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx и avx2.

Для правнуков, вот как получить имя производителя процессора с GCC, протестировано на 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);

Подобные встроенные функции также обычно зависят от компилятора.

MS VC++ имеет __cpuid__cpuidex) для генерации кода операции CPUID.

По крайней мере, насколько мне известно, gcc/g++ не обеспечивает аналога этому. Встроенная сборка кажется единственной доступной опцией.

Для x86/x64 Intel предоставляет встроенную функцию _may_i_use_cpu_feature, Вы можете найти его в категории " Общая поддержка " на странице Intel Intrinsics Guide. Ниже приведен разрыв документации Intel.

GCC предположительно следует за Intel в отношении встроенных функций, поэтому он должен быть доступен в рамках GCC. Мне не ясно, если Microsoft предоставит это, потому что они предоставляют большинство (но не все) встроенные компоненты Intel.

Я ничего не знаю о ARM. Насколько я знаю, нет __builtin_cpu_supports("neon"), __builtin_cpu_supports("crc32"), __builtin_cpu_supports("aes"), __builtin_cpu_supports("pmull"), __builtin_cpu_supports("sha") и т. д. под ARM. Для ARM вы должны выполнить проверку характеристик процессора.


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
Другие вопросы по тегам