__cpuid, __cpuidex
[Diese Dokumentation ist nur eine Vorschau und wird in späteren Versionen ggf. geändert. Blank topics are included as placeholders.]
Microsoft-spezifisch
Generiert die cpuid-Anweisung, die auf x86- und x64verfügbar ist. Abfragen dieser Anweisung der Prozessor Informationen über die unterstützten Funktionen und CPU geben ein.
void __cpuid(
int CPUInfo[4],
int InfoType
);
void __cpuidex(
int CPUInfo[4],
int InfoType,
int ECXValue
);
Parameter
[out] CPUInfo
Ein Array von vier ganzen Zahlen, das die erfassten Informationen zu unterstützten Funktionen und die CPU enthält.[in] InfoType
Der Code, der angibt, welche Informationen diese Anweisung abrufen.[in] ECXValue
Der Wert des ECX-Registers vor diesem systeminternen generiert die cpuid-Anweisung.
Anforderungen
Intrinsisch |
Architektur |
---|---|
__cpuid |
x86, x64 |
__cpuidex |
x86, x64 |
Headerdatei <intrin.h>
Hinweise
Diese Anweisung speichert die unterstützten Funktionen und CPU-Informationen in CPUInfo, ein Array von vier 32-Bit-Ganzzahlen, das mit den Werten der EAX-, EBX-, ECX- und EDX-Register gefüllt wird (in dieser Reihenfolge) nachdem Sie die cpuid-Anweisung aufrufen. Die Informationen haben eine andere Bedeutung je nach Wert, der InfoType das als Parameter übergeben wird. Die Informationen, die mit anderen Werten von InfoType zurückgegeben werden, sind Prozessor abhängiges Element.
Die systeminternen legt diesen fest __cpuidex der Wert des ECX-Registers, bevor die cpuid-Anweisung generiert. Dies ermöglicht es Ihnen, zusätzliche Informationen über den Prozessor zu erfassen.
Wenn das Argument 0 ist, InfoType folgenden Tabelle werden die die Ausgabe.
zurückgegebene Informationen
Arrayindex |
Bereich - Bit |
Beschreibung |
---|---|---|
0 |
0-31 |
Maximaler Wert für den InfoType-Parameter, der gültige Informationen zurückgibt. |
1 |
0-31 |
Identifikation Zeichenfolge (Teil 1) |
2 |
0-31 |
Identifikation Zeichenfolge (Teil 3) |
3 |
0-31 |
Identifikation Zeichenfolge (Teil 2) |
Wenn das Argument 1 ist, InfoType folgenden Tabelle werden die die Ausgabe.
CPU-Informationen zurückgegeben
Arrayindex |
Bereich - Bit |
Beschreibung |
---|---|---|
0 |
0-3 |
Bitten ID |
0 |
4-7 |
Modell |
0 |
8-11 |
Familie |
0 |
12-13 |
Prozessortyp (Intel) Reserviert (AMD) |
0 |
14-15 |
Reserviert. |
0 |
16-19 |
Erweitertes Modell |
0 |
20-27 |
Großfamilie |
0 |
28-31 |
Reserviert. |
1 |
0-7 |
Markierungen Zeilenindex |
1 |
8-15 |
Die Größe der Zeile, in Quadwords CLFLUSH-Cache |
1 |
16-23 |
Logische Anzahl der Prozessoren |
1 |
24-31 |
Ursprüngliche APIC-ID |
2 |
0 |
Neue Anweisungen SSE3 |
2 |
1-2 |
Reserviert. |
2 |
3 |
MONITOR/MWAIT |
2 |
4 |
Debuggen KOMPLETTES qualifiziertes Speicher (Intel) Reserviert (AMD) |
2 |
5 |
Erweiterungen des virtuellen Computers (Intel) Reserviert (AMD) |
2 |
6 |
Erweiterungen des sichereren Modus (Intel) Reserviert (AMD) |
2 |
7 |
Verbesserte Technologie Intel- SpeedStep (Intel) Reserviert (AMD) |
2 |
8 |
Thermischer Monitor (Intel) Reservierte (AMD) 2 |
2 |
9 |
Ergänzende Streaming SIMD-Erweiterungen 3 (SSSE3) |
2 |
10 |
Kontext-ID L1 (Intel) Reserviert (AMD) |
2 |
11 |
Reserviert. |
2 |
12 |
Erweiterungen von 256-Bit- FMA (Intel) Reserviert (AMD) |
2 |
13 |
CMPXCHG16B-Unterstützung |
2 |
14 |
xTPR Aktualisierung die Steuerung |
2 |
15 |
Perf MSR Funktion Debuggen/ |
2 |
16-17 |
Reserviert. |
2 |
18 |
Dynamische Unterstützung des Cache zugriffs (DCA) (Intel) Reserviert (AMD) |
2 |
19 |
Erweiterungen SSE4.1 |
2 |
20 |
Erweiterungen SSE4.2 |
2 |
21 |
x2APIC-Unterstützung (Intel) Reserviert (AMD) |
2 |
22 |
MOVBE-Unterstützung (Intel) Reserviert (AMD) |
2 |
23 |
Unterstützung POPCNT-Anweisungs |
2 |
24 |
Reserviert. |
2 |
25 |
AES-Unterstützung (Intel) Reserviert (AMD) |
2 |
26 |
XSAVE-Unterstützung (Intel) Reserviert (AMD) |
2 |
27 |
OSXSAVE-Unterstützung (Intel) Reserviert (AMD) |
2 |
28 |
Erweiterte Intel 256-Bit Vektor Namespaceerweiterungen (Intel) Reserviert (AMD) |
2 |
29-31 |
Reserviert. |
3 |
0-31 |
Featureinformationen (siehe weiter unten in diesem Thema) |
In der folgenden Tabelle wird die Bedeutung des Werts mit Funktion, der Wert von EDX an, CPUInfo [3] das geschrieben werden soll, wenn das InfoType-Argument 1 ist.
Funktions-Informationen zurückgegeben
Bit |
Zugriffstasten |
Beschreibung |
---|---|---|
0 |
FPU |
x87 FPU auf Chip |
1 |
VME |
Erweiterung des Modus Virtual-8086 |
2 |
DE |
Erweiterungen des Debuggens |
3 |
PSE |
extensions Seitengrößen |
4 |
TSC |
Zeitstempelleistungsindikator |
5 |
MSR |
RDMSR- und WRMSR-Unterstützung |
6 |
PAE |
Physische Adresserweiterungen |
7 |
MCE |
Maschinenprüfausnahme |
8 |
CX8 |
Anweisung CMPXCHG8 B |
9 |
APIC |
APIC auf Chip |
10 |
nicht verfügbar |
Reserviert. |
11 |
SEPT |
SYSENTER und SYSEXIT |
12 |
MTRR |
Arbeitsspeichertyp-Bereichsregister |
13 |
PGE |
Globales Bit PTE |
14 |
MCA |
Architektur der Maschinenprüf |
15 |
CMOV |
Bedingte Anweisung vergleichen und Verschieben |
16 |
PAT |
Seiten-Attribut-Tabelle |
17 |
PSE-36 |
Erweiterung der Seitengröße 36 bit |
18 |
PSN |
Seriennummer des Prozessor |
19 |
CLFSH |
CFLUSH-Anweisung |
20 |
nicht verfügbar |
Reserviert. |
21 |
DS |
Debuggen von Speicher |
22 |
ACPI |
Thermischer Bildschirm und Uhren-Steuerelement herangezogen |
23 |
MMX |
Technologie MMX |
24 |
FXSR |
FXSAVE/FXRSTOR |
25 |
SSE |
SSE-Erweiterungen |
26 |
SSE2-Anweisungen |
Erweiterungen SSE2-Anweisungen |
27 |
SS |
Auch schnüffler |
28 |
HTT |
Multithreading |
29 |
TM |
Thermischer Bildschirm |
30 |
nicht verfügbar |
Reserviert. |
31 |
PBE |
Beim Aktivieren Sie die Option Unterbrechen |
Hinweis
Mit dem AMD-Chipsatz alle vieladrige AMD CPU 28 Bit festgelegt datenbits Funktion anzugeben, dass der Chip mehr als einen Kern verfügt.Dies ist der Fall, obwohl AMD Hyper Threading nicht unterstützt.
Mehrere Prozessoren, wie die SSE3- und SSE4-enabled prozessoren, unterstützen zusätzliche InfoType-Werte. InfoType Wenn das Argument 2 ist, gibt die Anweisung Cache von Informationen in den codierten Forms zurück.
In der folgenden Tabelle sind die Werte an, die festlegen, wenn Sie diese Anweisung InfoType bis 4 zurückgibt. Dies ist eine Beziehung Informationen zum Cache wird der Cache auf. Um diese Informationen abzurufen, müssen Sie im ECX-Register festlegen. Verwenden Sie __cpuidex , das für das ECX auf den nullbasierten Index des Caches festlegen, ist systemintern abzufragende der obersten Ebene.
Deterministische Cache-Informationen
Array-Index |
Bit-Bereich |
Beschreibung |
---|---|---|
0 |
0-4 |
Cache im Feld Typ |
0 |
5-7 |
Cache Ebene |
0 |
8 |
Cache SELF-initialisieren |
0 |
9 |
Völlig vereinigender Cache |
0 |
10-13 |
Reserviert. |
0 |
14-25 |
Maximale Anzahl von Threads |
0 |
26-31 |
Maximale Anzahl von IDs für Prozessor verlaufen |
1 |
0-11 |
Größe kohärenz-Zeilen System |
1 |
12-21 |
Partitionen der physischen Zeile |
1 |
22-31 |
Assoziativität von Methoden |
2 |
0-31 |
Anzahl von Gruppen |
3 |
0-31 |
Reserviert. |
Wenn InfoType 5 ist, geben Informationen über den Bildschirm Prozessoren dieser Funktion (siehe _mm_monitor).
Wenn InfoType 6 Prozessor rückmeldung über die digitale Temperatur und die Energieverwaltung.
Wenn InfoType , 0x0A Prozessoren dieser Informationen, mit der die überwachte Architecture.
Mehrere Prozessoren unterstützen erweiterte Informationen CPUID Funktion. Wenn dies unterstützt wird, werden InfoType-Werte von 0x80000000, um Informationen verwendet werden. Um den maximal zulässigen sinnvollen Wert festzulegen, legen Sie InfoType zu 0x80000000 fest. Der maximale Wert InfoType unterstützte CPUInfo[0]geschrieben wird. In der folgenden Tabelle sind die Werte aufgeführt, die mithilfe der erweiterten Informationen CPUID der Funktion zurückgegeben werden.
Erweiterte Informationen Funktions-CPUID
InfoType |
Arrayindex |
Bereich - Bit |
Information |
---|---|---|---|
0x80000000 |
0 |
0-31 |
Maximaler sinnvoller Wert von InfoType Erweiterte Informationen zu CPUID der Funktion. |
0x80000000 |
1-3 |
0-31 |
Reserviert. |
0x80000001 |
0 |
0-31 |
Erweiterte Prozessor Methodensignatur und erweiterte Features Bits |
0x80000001 |
1 |
0-31 |
Reserviert. |
0x80000001 |
2 |
0 |
LAHF/SAHF verfügbar im 64-Bit-Modus |
0x80000001 |
2 |
1 |
Der Modus mehrprozessorbetrieb-Legacy Kern (CmpLegacy) (AMD) Reserviert (Intel) |
0x80000001 |
2 |
2 |
Speichern Sie den virtuellen Computer (SVM) (AMD) Reserviert (Intel) |
0x80000001 |
2 |
3 |
Erweitertes APIC-Register-Leerzeichen (ExtApicSpace) (AMD) Reserviert (Intel) |
0x80000001 |
2 |
4 |
AltMovCr8 (AMD) Reserviert (Intel) |
0x80000001 |
2 |
5 |
LZCNT-Unterstützung (AMD) Reserviert (Intel) |
0x80000001 |
2 |
6 |
Unterstützung SSE4A-Anweisungs (EXTRQ INSERTQ, MOVNTSD, MOVNTSS), (AMD) Reserviert (Intel) |
0x80000001 |
2 |
7 |
Falsch ausgerichtet SSE-Stütz Modus (AMD) verfügbar Reserviert (Intel) |
0x80000001 |
2 |
8 |
Unterstützung des VORZEITIGEN ABFANGENS und PREFETCHW (AMD) Reserviert (Intel) |
0x80000001 |
2 |
9-11 |
Reserviert. |
0x80000001 |
2 |
12 |
SKINIT- und Entwickler-Unterstützung (AMD) Reserviert (Intel) |
0x80000001 |
2 |
13-31 |
Reserviert. |
0x80000001 |
3 |
0-10 |
Reserviert. |
0x80000001 |
3 |
11 |
SYSCALL/SYSRET verfügbar im 64-Bit-Modus |
0x80000001 |
3 |
12-19 |
Reserviert. |
0x80000001 |
3 |
20 |
Führen Sie das verfügbare deaktivieren aus bit |
0x80000001 |
3 |
21 |
Reserviert. |
0x80000001 |
3 |
22 |
Erweiterungen für MMX Anweisungen (AMD) Reserviert (Intel) |
0x80000001 |
3 |
23-24 |
Reserviert. |
0x80000001 |
3 |
25 |
FFXSR (AMD) Reserviert (Intel) |
0x80000001 |
3 |
26 |
Unterstützung der Seite 1GB (AMD) Reserviert (Intel) |
0x80000001 |
3 |
27 |
RDTSCP-Unterstützung (AMD) Reserviert (Intel) |
0x80000001 |
3 |
28 |
Reserviert. |
0x80000001 |
3 |
29 |
64-Bit-Technologie verfügbar |
0x80000001 |
3 |
30 |
3DnowExt (AMD) Reserviert (Intel) |
0x80000001 |
3 |
31 |
3Dnow! Anweisungen (AMD) Reserviert (Intel) |
0x80000002 |
0-3 |
0-31 |
Prozessor marken Zeichenfolge |
0x80000003 |
0-3 |
0-31 |
fortgesetzt, marken Prozessor |
0x80000004 |
0-3 |
0-31 |
fortgesetzt, marken Prozessor |
0x80000005 |
0-3 |
0-31 |
Cache L1 und TLB-Bezeichner (AMD) Reserviert (Intel) |
0x80000006 |
0-1 |
0-31 |
Reserviert. |
0x80000006 |
2 |
0-7 |
Zwischenspeichern von Zeilengröße |
0x80000006 |
2 |
8-11 |
Reserviert. |
0x80000006 |
2 |
12-15 |
Assoziativität L2 |
0x80000006 |
2 |
16-31 |
Cachegröße in Einheiten 1K |
0x80000006 |
3 |
0-31 |
Reserviert. |
0x80000007 |
0-3 |
0-31 |
Advanced Power Management-Informationen (AMD) Reserviert (Intel) |
0x80000008 |
0 |
0-7 |
Bits physische Adresse |
0x80000008 |
0 |
8-15 |
Virtuelle Adressbits |
0x80000008 |
0 |
16-31 |
Reserviert. |
0x80000008 |
1-3 |
0-31 |
Reserviert. |
0x8000000A |
0 |
0-7 |
SVM-Revision (AMD) Reserviert (Intel) |
0x8000000A |
0 |
8-31 |
Reserviert. |
0x8000000A |
1 |
0-31 |
NASID - Zahl Adressraum-Bezeichner (AMD) Reserviert (Intel) |
0x8000000A |
2 |
0-31 |
Reserviert. |
0x8000000A |
3 |
0 |
Eine geschachtelte Paging (AMD) Reserviert (Intel) |
0x8000000A |
3 |
1 |
LBR-Visualisierung (AMD) Reserviert (Intel) |
0x8000000A |
3 |
2-31 |
Reserviert. |
0x80000019 |
0-3 |
0-31 |
Bezeichner der Seiten TLB (AMD) 1GB Reserviert (Intel) |
0x8000001A |
0 |
0 |
Optimierung FP128 (AMD) Reserviert (Intel) |
0x8000001A |
0 |
1 |
MOVU, MOVUPS, MOVUPD-Optimierung über MOVL/MOVH, MOVHLPS/MOVHPS, MOVLPD/MOVHPD (AMD) Reserviert (Intel) |
0x8000001A |
0 |
2-31 |
Reserviert. |
0x8000001A |
1-3 |
0-31 |
Reserviert. |
Beispiel
// cpuid.cpp
// processor: x86, x64
// Use the __cpuid intrinsic to get information about a CPU
#include <stdio.h>
#include <string.h>
#include <intrin.h>
const char* szFeatures[] =
{
"x87 FPU On Chip",
"Virtual-8086 Mode Enhancement",
"Debugging Extensions",
"Page Size Extensions",
"Time Stamp Counter",
"RDMSR and WRMSR Support",
"Physical Address Extensions",
"Machine Check Exception",
"CMPXCHG8B Instruction",
"APIC On Chip",
"Unknown1",
"SYSENTER and SYSEXIT",
"Memory Type Range Registers",
"PTE Global Bit",
"Machine Check Architecture",
"Conditional Move/Compare Instruction",
"Page Attribute Table",
"36-bit Page Size Extension",
"Processor Serial Number",
"CFLUSH Extension",
"Unknown2",
"Debug Store",
"Thermal Monitor and Clock Ctrl",
"MMX Technology",
"FXSAVE/FXRSTOR",
"SSE Extensions",
"SSE2 Extensions",
"Self Snoop",
"Multithreading Technology",
"Thermal Monitor",
"Unknown4",
"Pending Break Enable"
};
int main(int argc, char* argv[])
{
char CPUString[0x20];
char CPUBrandString[0x40];
int CPUInfo[4] = {-1};
int nSteppingID = 0;
int nModel = 0;
int nFamily = 0;
int nProcessorType = 0;
int nExtendedmodel = 0;
int nExtendedfamily = 0;
int nBrandIndex = 0;
int nCLFLUSHcachelinesize = 0;
int nLogicalProcessors = 0;
int nAPICPhysicalID = 0;
int nFeatureInfo = 0;
int nCacheLineSize = 0;
int nL2Associativity = 0;
int nCacheSizeK = 0;
int nPhysicalAddress = 0;
int nVirtualAddress = 0;
int nRet = 0;
int nCores = 0;
int nCacheType = 0;
int nCacheLevel = 0;
int nMaxThread = 0;
int nSysLineSize = 0;
int nPhysicalLinePartitions = 0;
int nWaysAssociativity = 0;
int nNumberSets = 0;
unsigned nIds, nExIds, i;
bool bSSE3Instructions = false;
bool bMONITOR_MWAIT = false;
bool bCPLQualifiedDebugStore = false;
bool bVirtualMachineExtensions = false;
bool bEnhancedIntelSpeedStepTechnology = false;
bool bThermalMonitor2 = false;
bool bSupplementalSSE3 = false;
bool bL1ContextID = false;
bool bCMPXCHG16B = false;
bool bxTPRUpdateControl = false;
bool bPerfDebugCapabilityMSR = false;
bool bSSE41Extensions = false;
bool bSSE42Extensions = false;
bool bPOPCNT = false;
bool bMultithreading = false;
bool bLAHF_SAHFAvailable = false;
bool bCmpLegacy = false;
bool bSVM = false;
bool bExtApicSpace = false;
bool bAltMovCr8 = false;
bool bLZCNT = false;
bool bSSE4A = false;
bool bMisalignedSSE = false;
bool bPREFETCH = false;
bool bSKINITandDEV = false;
bool bSYSCALL_SYSRETAvailable = false;
bool bExecuteDisableBitAvailable = false;
bool bMMXExtensions = false;
bool bFFXSR = false;
bool b1GBSupport = false;
bool bRDTSCP = false;
bool b64Available = false;
bool b3DNowExt = false;
bool b3DNow = false;
bool bNestedPaging = false;
bool bLBRVisualization = false;
bool bFP128 = false;
bool bMOVOptimization = false;
bool bSelfInit = false;
bool bFullyAssociative = false;
// __cpuid with an InfoType argument of 0 returns the number of
// valid Ids in CPUInfo[0] and the CPU identification string in
// the other three array elements. The CPU identification string is
// not in linear order. The code below arranges the information
// in a human readable form.
__cpuid(CPUInfo, 0);
nIds = CPUInfo[0];
memset(CPUString, 0, sizeof(CPUString));
*((int*)CPUString) = CPUInfo[1];
*((int*)(CPUString+4)) = CPUInfo[3];
*((int*)(CPUString+8)) = CPUInfo[2];
// Get the information associated with each valid Id
for (i=0; i<=nIds; ++i)
{
__cpuid(CPUInfo, i);
printf_s("\nFor InfoType %d\n", i);
printf_s("CPUInfo[0] = 0x%x\n", CPUInfo[0]);
printf_s("CPUInfo[1] = 0x%x\n", CPUInfo[1]);
printf_s("CPUInfo[2] = 0x%x\n", CPUInfo[2]);
printf_s("CPUInfo[3] = 0x%x\n", CPUInfo[3]);
// Interpret CPU feature information.
if (i == 1)
{
nSteppingID = CPUInfo[0] & 0xf;
nModel = (CPUInfo[0] >> 4) & 0xf;
nFamily = (CPUInfo[0] >> 8) & 0xf;
nProcessorType = (CPUInfo[0] >> 12) & 0x3;
nExtendedmodel = (CPUInfo[0] >> 16) & 0xf;
nExtendedfamily = (CPUInfo[0] >> 20) & 0xff;
nBrandIndex = CPUInfo[1] & 0xff;
nCLFLUSHcachelinesize = ((CPUInfo[1] >> 8) & 0xff) * 8;
nLogicalProcessors = ((CPUInfo[1] >> 16) & 0xff);
nAPICPhysicalID = (CPUInfo[1] >> 24) & 0xff;
bSSE3Instructions = (CPUInfo[2] & 0x1) || false;
bMONITOR_MWAIT = (CPUInfo[2] & 0x8) || false;
bCPLQualifiedDebugStore = (CPUInfo[2] & 0x10) || false;
bVirtualMachineExtensions = (CPUInfo[2] & 0x20) || false;
bEnhancedIntelSpeedStepTechnology = (CPUInfo[2] & 0x80) || false;
bThermalMonitor2 = (CPUInfo[2] & 0x100) || false;
bSupplementalSSE3 = (CPUInfo[2] & 0x200) || false;
bL1ContextID = (CPUInfo[2] & 0x300) || false;
bCMPXCHG16B= (CPUInfo[2] & 0x2000) || false;
bxTPRUpdateControl = (CPUInfo[2] & 0x4000) || false;
bPerfDebugCapabilityMSR = (CPUInfo[2] & 0x8000) || false;
bSSE41Extensions = (CPUInfo[2] & 0x80000) || false;
bSSE42Extensions = (CPUInfo[2] & 0x100000) || false;
bPOPCNT= (CPUInfo[2] & 0x800000) || false;
nFeatureInfo = CPUInfo[3];
bMultithreading = (nFeatureInfo & (1 << 28)) || false;
}
}
// Calling __cpuid with 0x80000000 as the InfoType argument
// gets the number of valid extended IDs.
__cpuid(CPUInfo, 0x80000000);
nExIds = CPUInfo[0];
memset(CPUBrandString, 0, sizeof(CPUBrandString));
// Get the information associated with each extended ID.
for (i=0x80000000; i<=nExIds; ++i)
{
__cpuid(CPUInfo, i);
printf_s("\nFor InfoType %x\n", i);
printf_s("CPUInfo[0] = 0x%x\n", CPUInfo[0]);
printf_s("CPUInfo[1] = 0x%x\n", CPUInfo[1]);
printf_s("CPUInfo[2] = 0x%x\n", CPUInfo[2]);
printf_s("CPUInfo[3] = 0x%x\n", CPUInfo[3]);
if (i == 0x80000001)
{
bLAHF_SAHFAvailable = (CPUInfo[2] & 0x1) || false;
bCmpLegacy = (CPUInfo[2] & 0x2) || false;
bSVM = (CPUInfo[2] & 0x4) || false;
bExtApicSpace = (CPUInfo[2] & 0x8) || false;
bAltMovCr8 = (CPUInfo[2] & 0x10) || false;
bLZCNT = (CPUInfo[2] & 0x20) || false;
bSSE4A = (CPUInfo[2] & 0x40) || false;
bMisalignedSSE = (CPUInfo[2] & 0x80) || false;
bPREFETCH = (CPUInfo[2] & 0x100) || false;
bSKINITandDEV = (CPUInfo[2] & 0x1000) || false;
bSYSCALL_SYSRETAvailable = (CPUInfo[3] & 0x800) || false;
bExecuteDisableBitAvailable = (CPUInfo[3] & 0x10000) || false;
bMMXExtensions = (CPUInfo[3] & 0x40000) || false;
bFFXSR = (CPUInfo[3] & 0x200000) || false;
b1GBSupport = (CPUInfo[3] & 0x400000) || false;
bRDTSCP = (CPUInfo[3] & 0x8000000) || false;
b64Available = (CPUInfo[3] & 0x20000000) || false;
b3DNowExt = (CPUInfo[3] & 0x40000000) || false;
b3DNow = (CPUInfo[3] & 0x80000000) || false;
}
// Interpret CPU brand string and cache information.
if (i == 0x80000002)
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000003)
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000004)
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000006)
{
nCacheLineSize = CPUInfo[2] & 0xff;
nL2Associativity = (CPUInfo[2] >> 12) & 0xf;
nCacheSizeK = (CPUInfo[2] >> 16) & 0xffff;
}
else if (i == 0x80000008)
{
nPhysicalAddress = CPUInfo[0] & 0xff;
nVirtualAddress = (CPUInfo[0] >> 8) & 0xff;
}
else if (i == 0x8000000A)
{
bNestedPaging = (CPUInfo[3] & 0x1) || false;
bLBRVisualization = (CPUInfo[3] & 0x2) || false;
}
else if (i == 0x8000001A)
{
bFP128 = (CPUInfo[0] & 0x1) || false;
bMOVOptimization = (CPUInfo[0] & 0x2) || false;
}
}
// Display all the information in user-friendly format.
printf_s("\n\nCPU String: %s\n", CPUString);
if (nIds >= 1)
{
if (nSteppingID)
printf_s("Stepping ID = %d\n", nSteppingID);
if (nModel)
printf_s("Model = %d\n", nModel);
if (nFamily)
printf_s("Family = %d\n", nFamily);
if (nProcessorType)
printf_s("Processor Type = %d\n", nProcessorType);
if (nExtendedmodel)
printf_s("Extended model = %d\n", nExtendedmodel);
if (nExtendedfamily)
printf_s("Extended family = %d\n", nExtendedfamily);
if (nBrandIndex)
printf_s("Brand Index = %d\n", nBrandIndex);
if (nCLFLUSHcachelinesize)
printf_s("CLFLUSH cache line size = %d\n",
nCLFLUSHcachelinesize);
if (bMultithreading && (nLogicalProcessors > 0))
printf_s("Logical Processor Count = %d\n", nLogicalProcessors);
if (nAPICPhysicalID)
printf_s("APIC Physical ID = %d\n", nAPICPhysicalID);
if (nFeatureInfo || bSSE3Instructions ||
bMONITOR_MWAIT || bCPLQualifiedDebugStore ||
bVirtualMachineExtensions || bEnhancedIntelSpeedStepTechnology ||
bThermalMonitor2 || bSupplementalSSE3 || bL1ContextID ||
bCMPXCHG16B || bxTPRUpdateControl || bPerfDebugCapabilityMSR ||
bSSE41Extensions || bSSE42Extensions || bPOPCNT ||
bLAHF_SAHFAvailable || bCmpLegacy || bSVM ||
bExtApicSpace || bAltMovCr8 ||
bLZCNT || bSSE4A || bMisalignedSSE ||
bPREFETCH || bSKINITandDEV || bSYSCALL_SYSRETAvailable ||
bExecuteDisableBitAvailable || bMMXExtensions || bFFXSR || b1GBSupport ||
bRDTSCP || b64Available || b3DNowExt || b3DNow || bNestedPaging ||
bLBRVisualization || bFP128 || bMOVOptimization )
{
printf_s("\nThe following features are supported:\n");
if (bSSE3Instructions)
printf_s("\tSSE3\n");
if (bMONITOR_MWAIT)
printf_s("\tMONITOR/MWAIT\n");
if (bCPLQualifiedDebugStore)
printf_s("\tCPL Qualified Debug Store\n");
if (bVirtualMachineExtensions)
printf_s("\tVirtual Machine Extensions\n");
if (bEnhancedIntelSpeedStepTechnology)
printf_s("\tEnhanced Intel SpeedStep Technology\n");
if (bThermalMonitor2)
printf_s("\tThermal Monitor 2\n");
if (bSupplementalSSE3)
printf_s("\tSupplemental Streaming SIMD Extensions 3\n");
if (bL1ContextID)
printf_s("\tL1 Context ID\n");
if (bCMPXCHG16B)
printf_s("\tCMPXCHG16B Instruction\n");
if (bxTPRUpdateControl)
printf_s("\txTPR Update Control\n");
if (bPerfDebugCapabilityMSR)
printf_s("\tPerf\\Debug Capability MSR\n");
if (bSSE41Extensions)
printf_s("\tSSE4.1 Extensions\n");
if (bSSE42Extensions)
printf_s("\tSSE4.2 Extensions\n");
if (bPOPCNT)
printf_s("\tPPOPCNT Instruction\n");
i = 0;
nIds = 1;
while (i < (sizeof(szFeatures)/sizeof(const char*)))
{
if (nFeatureInfo & nIds)
{
printf_s("\t");
printf_s(szFeatures[i]);
printf_s("\n");
}
nIds <<= 1;
++i;
}
if (bLAHF_SAHFAvailable)
printf_s("\tLAHF/SAHF in 64-bit mode\n");
if (bCmpLegacy)
printf_s("\tCore multi-processing legacy mode\n");
if (bSVM)
printf_s("\tSecure Virtual Machine\n");
if (bExtApicSpace)
printf_s("\tExtended APIC Register Space\n");
if (bAltMovCr8)
printf_s("\tAltMovCr8\n");
if (bLZCNT)
printf_s("\tLZCNT instruction\n");
if (bSSE4A)
printf_s("\tSSE4A (EXTRQ, INSERTQ, MOVNTSD, MOVNTSS)\n");
if (bMisalignedSSE)
printf_s("\tMisaligned SSE mode\n");
if (bPREFETCH)
printf_s("\tPREFETCH and PREFETCHW Instructions\n");
if (bSKINITandDEV)
printf_s("\tSKINIT and DEV support\n");
if (bSYSCALL_SYSRETAvailable)
printf_s("\tSYSCALL/SYSRET in 64-bit mode\n");
if (bExecuteDisableBitAvailable)
printf_s("\tExecute Disable Bit\n");
if (bMMXExtensions)
printf_s("\tExtensions to MMX Instructions\n");
if (bFFXSR)
printf_s("\tFFXSR\n");
if (b1GBSupport)
printf_s("\t1GB page support\n");
if (bRDTSCP)
printf_s("\tRDTSCP instruction\n");
if (b64Available)
printf_s("\t64 bit Technology\n");
if (b3DNowExt)
printf_s("\t3Dnow Ext\n");
if (b3DNow)
printf_s("\t3Dnow! instructions\n");
if (bNestedPaging)
printf_s("\tNested Paging\n");
if (bLBRVisualization)
printf_s("\tLBR Visualization\n");
if (bFP128)
printf_s("\tFP128 optimization\n");
if (bMOVOptimization)
printf_s("\tMOVU Optimization\n");
}
}
if (nExIds >= 0x80000004)
printf_s("\nCPU Brand String: %s\n", CPUBrandString);
if (nExIds >= 0x80000006)
{
printf_s("Cache Line Size = %d\n", nCacheLineSize);
printf_s("L2 Associativity = %d\n", nL2Associativity);
printf_s("Cache Size = %dK\n", nCacheSizeK);
}
for (i=0;;i++)
{
__cpuidex(CPUInfo, 0x4, i);
if(!(CPUInfo[0] & 0xf0)) break;
if(i == 0)
{
nCores = CPUInfo[0] >> 26;
printf_s("\n\nNumber of Cores = %d\n", nCores + 1);
}
nCacheType = (CPUInfo[0] & 0x1f);
nCacheLevel = (CPUInfo[0] & 0xe0) >> 5;
bSelfInit = (CPUInfo[0] & 0x100) >> 8;
bFullyAssociative = (CPUInfo[0] & 0x200) >> 9;
nMaxThread = (CPUInfo[0] & 0x03ffc000) >> 14;
nSysLineSize = (CPUInfo[1] & 0x0fff);
nPhysicalLinePartitions = (CPUInfo[1] & 0x03ff000) >> 12;
nWaysAssociativity = (CPUInfo[1]) >> 22;
nNumberSets = CPUInfo[2];
printf_s("\n");
printf_s("ECX Index %d\n", i);
switch (nCacheType)
{
case 0:
printf_s(" Type: Null\n");
break;
case 1:
printf_s(" Type: Data Cache\n");
break;
case 2:
printf_s(" Type: Instruction Cache\n");
break;
case 3:
printf_s(" Type: Unified Cache\n");
break;
default:
printf_s(" Type: Unknown\n");
}
printf_s(" Level = %d\n", nCacheLevel + 1);
if (bSelfInit)
{
printf_s(" Self Initializing\n");
}
else
{
printf_s(" Not Self Initializing\n");
}
if (bFullyAssociative)
{
printf_s(" Is Fully Associatve\n");
}
else
{
printf_s(" Is Not Fully Associatve\n");
}
printf_s(" Max Threads = %d\n",
nMaxThread+1);
printf_s(" System Line Size = %d\n",
nSysLineSize+1);
printf_s(" Physical Line Partions = %d\n",
nPhysicalLinePartitions+1);
printf_s(" Ways of Associativity = %d\n",
nWaysAssociativity+1);
printf_s(" Number of Sets = %d\n",
nNumberSets+1);
}
return nRet;
}