2013-07-20 14 views
14

Biorąc pod uwagę, że jestem kodowania w C++, jeśli to możliwe, chciałbym użyć intrinsics-podobnego rozwiązania czytać użytecznych informacji o sprzęcie, moje obawy/rozważania są:Intrinsics for CPUID like information?

  • Nie wiem montaż cóż, będzie to znaczna inwestycja tylko po to, by zdobyć tego rodzaju informacje (choć wygląda na to, że CPU to tylko przerzucanie wartości i czytanie rejestrów).
  • istnieje co najmniej 2 popularne składnie dla asm (Intel i AT & T) , więc jest rozdrobniony
  • co dziwne Intrinsics są bardziej popularne i obsługiwane niż kod ASM w dzisiejszych czasach
  • Nie wszystkie kompilatory, które są teraz w moim radarem, obsługują wbudowany asm, 64-bitowy MSVC to jeden; Obawiam się, że znajdę inne podobne wady, kopiąc więcej w zestawy funkcji różnych kompilatorów, których muszę użyć.
  • biorąc pod uwagę trand Myślę, że jest bardziej produktywne dla mnie, aby postawić na Intrinsics, powinno być również o wiele łatwiejsze niż jakikolwiek kod asm.

I ostatnie pytanie, na które muszę odpowiedzieć, brzmi: jak zrobić coś podobnego z wewnętrznym? Ponieważ nie znalazłem niczego innego niż opcodes CPUID, aby uzyskać tego rodzaju informacje w ogóle.

+0

Clang posiada zintegrowany asembler, a jego wsparcie dla zespołu Intel stylu jest rzadki w czasie. Nie może wygenerować prostego 'negate (neg)' w stylu Intela. – jww

Odpowiedz

10

Po kilku kopaniu I have found użyteczne wbudowane funkcje, które są specyficzne dla gcc.

Jedynym problemem jest to, że tego rodzaju funkcje są bardzo ograniczone (w zasadzie masz tylko 2 funkcje, 1 dla procesora „nazwa” i 1 dla zbioru rejestrów)

przykładem jest

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

i podobno te wbudowane funkcje działają również pod mingw-w64.

+0

Od pytania: * "nie wszystkie kompilatory ... obsługują wbudowany asm, MSVC 64 bit to jeden" *. Podany kod z pewnością nie działa na kompilatorach Microsoft. Powinieneś unikać akceptowania swojej odpowiedzi, dopóki nie będziesz miał rozwiązań GCC i MS. – jww

7

Takie elementy charakterystyczne są zazwyczaj specyficzne dla kompilatora.

MS VC++ ma __cpuid (i __cpuidex) do generowania kodu operacyjnego CPUID.

Co najmniej z tego, co wiem, gcc/g ++ nie zapewnia tego odpowiednika. Inline assembly wydaje się być jedyną dostępną opcją.

+1

Znalazłem coś http://stackoverflow.com/a/17759098/2485710 – user2485710

+1

gcc udostępnia nagłówek 'cpuid.h', który udostępnia makro' __cpuid' (inaczej zdefiniowane niż MSVC) oraz '__get_cpuid' funkcjonować. – rdb

6

Gcc zawiera interfejs CPUID:

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

te nie wydają się być dobrze udokumentowane, ale przykładów użycia można znaleźć tutaj:

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

Zauważ, że musisz użyj wartości __cpuid_count(), a nie __cpuid(), gdy liczy się wartość początkowa ekx, na przykład przy wykryciu avx/avx2.

Jak wskazano w user2485710, gcc może wykonać dla Ciebie wszystkie funkcje wykrywania funkcji procesora. Od wersji gcc 4.8.1 pełna lista funkcji obsługiwanych przez __builtin_cpu_supports() to: cmov, mmx, popcnt, sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx i avx2.

2

W przypadku architektury x86/x64 firma Intel zapewnia wewnętrzny kod o nazwie _may_i_use_cpu_feature. Można go znaleźć pod kategorią Ogólne wsparcie strony Intel Intrinsics Guide. Poniżej znajduje się zgrywanie dokumentacji Intela.

GCC rzekomo podąża za Intelem w odniesieniu do elementów wewnętrznych, więc powinien być dostępny pod GCC. Nie jest dla mnie jasne, czy Microsoft to zapewnia, ponieważ zapewniają one większość (ale nie wszystkie) intrinsics Intela.

Nic nie wiem o ARM. O ile mi wiadomo, w obszarze ARM nie ma numerów __builtin_cpu_supports("neon"), , __builtin_cpu_supports("aes"),, __builtin_cpu_supports("sha"). W przypadku ARM musisz wykonać 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