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

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

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

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

15

Решение

После некоторого копания я нашел полезные встроенные функции, специфичные для 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.

10

Другие решения

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

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

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

7

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.

7

Для 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
3

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