| Friday, 24 May 2013 | |
|
|
|
|
|
|
|
|
CPU Detection
|
| Level | Description |
|---|---|
| 0x00000000 | Retrieve maximum standard level and processor name |
| 0x00000001 |
Get processor type/family/model/stepping and feature flags |
| 0x00000002 |
Get processor details (cache information) |
| 0x00000003 |
Get processor serial number (Pentium III only) |
| 0x00000004 |
Get cache details |
| 0x00000005 |
Retrieve MON information |
| 0x00000006 |
Get power management information |
| 0x80000000 |
Retrieve maximum extended level and processor name |
| 0x80000001 |
Get processor type/family/model/stepping and extended feature flags |
| 0x80000002 |
Get first part of long processor name |
| 0x80000003 |
Get second part of long processor name |
| 0x80000004 | Get third and last part of long processof name |
| 0x80000005 |
Get L1 Cache and TLB information |
| 0x80000006 |
Get L2 Cache information |
| 0x80000007 |
Retrieve extended power information |
The levels with bit 31 set are called extended level, all other levels are called standard level.
The xplCPU implementation provides a function called xplCPU_cpuid, which takes the level as an input parameter and executes a CPUID instruction and returns the result in a regular C structure. This function has different implementation for various platforms and compilers.
The following sections of this article will show how to retrieve information using the CPUID instruction.
The name of a processor is stored within the processor and can be read using the CPUID instruction. To retrieve the processors' name you have to load 0x00000000 (standard level 0) to the EAX register before issueing the CPUID instruction.
After the CPUID instruction has been executed, the EAX register holds the maximum supported standard level for the CPUID. The name of the processor is returned in the EBX, ECX and EDX registers. Each of these registers hold four characters of the name, so the name string is at most 12 bytes long. Here's the basic code to retrieve the name of the processor.
mov eax, 0h
cpuid mov max_level, eax
mov name+0h, ebx
mov name+4h, edx
mov name+8h, ecx
The supported features of the processorcan be determined by using the standard level 1 and extended level 1 of the CPUID instruction.
By calling CPUID with EAX=1 the processor returns the processor features in the ECX and EDX registers. The EAX registers contains the processors family, its model and stepping. The EBX register contains information about manufacturing, but only some processors provide useful information in this register.
Here is a list of the most interesting features returned in the EDX register:
| Bit | Description |
|---|---|
| 0 | FPU present |
| 4 |
Processors time count is available; required to determine CPU speed |
| 9 |
Advanced Programmable Interrupt Controller present and enabled |
| 23 |
MMX present |
| 25 | SSE present |
| 26 |
SSE2 present |
| 28 |
Intel Hyper-Threading Technology |
| 30 |
Intel IA-64 instructions present |
The extended support level 1 work the same way as standard level 1, but returns a different set of features. The meaning of the EAX register is the same, but the mean of the other registers is quite different.
The following table lists the interesting features reported by CPUID instruction with extended support level 1 in the EDX register:
| Bit | Description |
|---|---|
| 22 |
MMX+ present (AMD specific) |
| 23 |
MMX present |
| 29 |
AA-64 Long Mode available (64-Bit computing) |
| 30 |
extended 3DNow!+ present |
| 31 |
3DNow! present |
There are several other bits which indicate that special instruction are available or certain features are present on the processor. A good reference for the processor features can be found on [2] .
The speed of the processor can be determined by using the RDTSC instruction. This instruction returns the number of clock-cycles, which happened since the processor got power.
The method to measure the CPU speed is quite simple:
Measure the CPU speed in real-world is a bit more complicated. The method is still the same, but there are some difficulties, which must be take care of.
The xplCPU class, which is shipped with the libxpl library, takes care about all these points mentioned above. It's using a thread, which runs with the highest possible thread priority during the measurement to avoid context switches and to get the best possible time measurement. It does not use any OS functions to wait one second, instead xplCPU uses a simple loop, which aborts after one millisecond. Since there a variation in each measurement, xplCPU uses at least the result of three measurements and calculate the average of these.
The libxpl library includes a class named xplCPU, which provides all function to perform a CPU detection and provide the use with all information about the processor. xplCPU can be used on any platform supported by the libxpl, which are at the moment Win32 and Linux.
The following example shows the usage of the xplCPU class:
UINT nNumCPUs = xplCPU::GetNumberOfCPUs();
printf("Number of CPUs %i\n",nNumCPUs);
for(UINT n = 0; n < nNumCPUs; n++)
{
const xplCPU * pCPU = xplCPU::GetCPU(n);
ASSERT(pCPU != NULL);
printf("CPU%i: %s\n",n,pCPU->GetName());
if(pCPU->IsFeaturePresent(xplCPUFeatureMMX))
printf("CPU%i: MMX present\n",n);
}
This article shows how to perform a proper CPU detection. It describes the basic technology to get the required information and also gives a brief introduction of the xplCPU class included in the libxpl library.
If you requires some assistance using the xplCPU class or would like some more information about CPU detection do not hesitate to contact me.
| < Prev |
|---|
|
| Copyright © by AR Soft 2005-2013 | ||