2013-07-20 19 views
14

man bedenkt, dass ich in C++ bin Codierung, wenn möglich, würde Ich mag eine Intrinsics-ähnliche Lösung verwenden, nützliche Informationen über die Hardware zu lesen, meine Bedenken/Überlegungen sind:Intrinsics für CPUID wie Informationen?

  • Ich weiß nicht, Montag Nun, es wird eine beträchtliche Investition sein, nur um diese Art von Informationen zu bekommen (obwohl es wie CPU aussieht, dreht es sich nur um Werte spiegeln und Register lesen.)
  • dort mindestens 2 beliebte Syntax für asm (Intel und AT & T) , so ist es fragmentiert
  • seltsam genug Intrinsics sind beliebter und unterstützt als Asm-Code in diesen Tagen
  • nicht alle Compiler, die derzeit in meinem Radar sind, unterstützen Inline-Asm, MSVC 64 Bit ist eins; Ich befürchte, dass ich andere ähnliche Fehler finden werde, wenn ich mehr in die Feature-Sets der verschiedenen Compiler, die ich benutzen muss, eingrabe.
  • unter Berücksichtigung der Trand Ich denke, dass es produktiver für mich ist, auf Intrinsics wetten, sollte es auch viel einfacher als jeder Asm-Code.

Und die letzte Frage, die ich beantworten muss, ist: Wie man eine ähnliche Sache mit intrinsics macht? Weil ich nichts anderes als CPUID-Opcodes gefunden habe, um diese Art von Informationen überhaupt zu bekommen.

+0

Clang verfügt über einen integrierten Assembler und seine Unterstützung für die Montage Intel-Stil ist manchmal fleckig. Es kann kein einfaches 'negate (neg)' unter Intel-Stil erzeugen. – jww

Antwort

10

Nach einigen Graben I have found eine nützliche integrierte Funktionen, die gcc spezifisch ist.

Das einzige Problem ist, dass diese Art von Funktionen wirklich begrenzt ist (im Grunde haben Sie nur zwei Funktionen, 1 für die CPU „namen“ und 1 für den Satz von Registern)

ein Beispiel ist

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

und anscheinend funktionieren diese eingebauten Funktionen auch unter mingw-w64.

+0

Von der Frage: * "nicht alle Compiler ... unterstützen Inline-Asm, MSVC 64 Bit ist eins" *. Der mitgelieferte Code funktioniert bei Microsoft Compilern sicherlich nicht. Sie sollten Ihre Antwort nicht akzeptieren, bis Sie sowohl GCC- als auch MS-Lösungen haben. – jww

7

Intrinsics wie diese sind auch in der Regel Compiler-spezifisch.

MS VC++ hat eine __cpuid (und eine __cpuidex), um einen CPUID-Op-Code zu generieren.

Zumindest soweit ich weiß, gcc/g ++ bietet keine Entsprechung dazu. Inline Assembly scheint die einzige verfügbare Option zu sein.

+1

Ich habe etwas gefunden http://stackoverflow.com/a/17759098/2485710 – user2485710

+1

gcc bietet eine 'cpuid.h'-Header, die eine' __cpuid' Makro (definiert anders als MSVCs, wohlgemerkt) sowie eine '__get_cpuid' zur Verfügung stellt Funktion. – rdb

6

Gcc enthält eine cpuid Schnittstelle:

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

Diese scheinen nicht gut dokumentiert werden, sondern beispielsweise Verwendung finden Sie hier:

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

Beachten Sie, dass Sie muss Verwenden Sie __cpuid_count() und nicht __cpuid(), wenn der Anfangswert von ecx von Bedeutung ist, z. B. bei der Erkennung von avx/avx2.

Wie Benutzer2485710 darauf hingewiesen hat, kann gcc alle CPU-Erkennungsfunktionen für Sie erledigen. Ab gcc 4.8.1 lautet die vollständige Liste der von __builtin_cpu_supports() unterstützten Funktionen: cmov, mmx, popcnt, sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx und avx2.

2

Für x86/x64 bietet Intel einen intrinsischen namens _may_i_use_cpu_feature. Sie können es unter der General Support Kategorie der Intel Intrinsics Guide Seite finden. Unten ist ein Riss von Intels Dokumentation.

GCC folgt angeblich Intel in Bezug auf intrinsics, so sollte es unter GCC verfügbar sein. Es ist mir nicht klar, ob Microsoft es anbietet, weil sie die meisten (aber nicht alle) Intel-Intrinsics liefern.

Mir ist nichts für ARM bekannt. Soweit ich weiß, gibt es keine __builtin_cpu_supports("neon"), __builtin_cpu_supports("crc32"), __builtin_cpu_supports("aes"), __builtin_cpu_supports("pmull"), __builtin_cpu_supports("sha") usw. unter ARM. Für ARM müssen Sie CPU feature probing ausführen.


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