Home -- Download -- Documentation -- Bug report -- News

Library reference

The complete library reference (generated by Doxygen from latest sources) is available here


Quickstart tutorial

This is a short NeHe-style tutorial, but it provides only basic overview. Some of the features are not demonstrated here.

#include <stdio.h>
#include <libcpuid.h>

Include the library's main header. The development headers must be placed in your search path. Under UNIX-like OSes with pkg-config, this is achieved with "pkg-config libcpuid --cflags".


int main(void)
{
	if (!cpuid_present()) {                                                // check for CPUID presence
		printf("Sorry, your CPU doesn't support CPUID!\n");
		return -1;
	}

On some very old CPUs, the CPUID instruction may be absent. We check for that here.

	
	struct cpu_raw_data_t raw;                                             // contains only raw data
	struct cpu_id_t data;                                                  // contains recognized CPU features data

There are two main structures here. The cpu_raw_data_t contains only RAW CPUID data, directly obtained from the CPU.
The cpu_id_t contains the decoded CPU information - i.e. all that we really care about.


	if (cpuid_get_raw_data(&raw) < 0) {                                    // obtain the raw CPUID data
		printf("Sorry, cannot get the CPUID raw data.\n");
		printf("Error: %s\n", cpuid_error());                          // cpuid_error() gives the last error description
		return -2;
	}

In some cases, we might be unable to fetch any CPUID data. The cpuid_error() function is used to report what kind of error was encountered.


	if (cpu_identify(&raw, &data) < 0) {                                   // identify the CPU, using the given raw data.
		printf("Sorrry, CPU identification failed.\n");
		printf("Error: %s\n", cpuid_error());
		return -3;
	}

Now we do CPU identification. This function fills the "data" structure with the recognized CPU features.


	printf("Found: %s CPU\n", data.vendor_str);                            // print out the vendor string (e.g. `GenuineIntel')
	printf("Processor model is `%s'\n", data.cpu_codename);                // print out the CPU code name (e.g. `Pentium 4 (Northwood)')
	printf("The full brand string is `%s'\n", data.brand_str);             // print out the CPU brand string
	printf("The processor has %dK L1 cache and %dK L2 cache\n",
		data.l1_data_cache, data.l2_cache);                            // print out cache size information
	printf("The processor has %d cores and %d logical processors\n",
		data.num_cores, data.num_logical_cpus);                        // print out CPU cores information

Here we basically exploit the data and print out some stuff. We can't really assume we have all the data filled in - but if something is not recognized (e.g. cache size is not filled in), there will be safe "uninitialized" values for the fields (e.g. empty strings, -1 for cache sizes, etc.).


	printf("Supported multimedia instruction sets:\n");
	printf("  MMX         : %s\n", data.flags[CPU_FEATURE_MMX] ? "present" : "absent");
	printf("  MMX-extended: %s\n", data.flags[CPU_FEATURE_MMXEXT] ? "present" : "absent");
	printf("  SSE         : %s\n", data.flags[CPU_FEATURE_SSE] ? "present" : "absent");
	printf("  SSE2        : %s\n", data.flags[CPU_FEATURE_SSE2] ? "present" : "absent");
	printf("  3DNow!      : %s\n", data.flags[CPU_FEATURE_3DNOW] ? "present" : "absent");

We check for presence of specific CPU features. There are two points to be made here:

  1. If you run the above code on an Intel CPU, it will report absence of the MMX-extended set, even if it has SSE. Actually, the MMX-extended is a proper subset of the SSE (these are the integer SSE instructions, which extend the original MMX set - added by Intel with SSE and also supported by some AMD CPUs, which do not otherwise support the full SSE set). This means, that, for Intel CPUs, presence of the SSE set (or later) implies the presence of MMX-ext. The general rule is that libcpuid reports just what the CPU says - it doesn't try to be smart in cases like this.
  2. If you need this kind of feature detection, it is recommended to execute cpu_identify() only once and save the results somewhere; calling cpu_identify() or cpuid_get_raw_data() too many times (e.g. several hundred times per second) can hinder performance significantly.

	printf("CPU clock is: %d MHz (according to your OS)\n",
		cpu_clock_by_os());                                            // print out the CPU clock, according to the OS
	printf("CPU clock is: %d MHz (tested)\n", cpu_clock_measure(200, 0));  // print out the CPU clock, measured with RDTSC.

Get the CPU clock speed, in MHz. There are several ways to do that, and here we demonstrate two of them: using OS routines, and measurement using a busy-wait cycle with RDTSC (the parameters here are the length of the busy-wait cycle, in milliseconds, and whether to use a stronger type of detection (quadruple-checking). See the doxygen docs for more details).


	return 0;
}

Compile with the library linked in. E.g., in UNIX-like environments, use "gcc -o example example.c `pkg-config libcpuid --cflags --libs`"


All brand names and product names mentioned here are trademarks or registered trademarks of their respective owners.

SourceForge.net Logo