Using ‘cpuid’ instructions to get cache line size

Written by

in

This is program demonstrates how to use ‘cpuid’ assembly instruction on x86 to retrieve cache line size. This is done in c++ and it uses the inline assembly to execute the instructions, compiled with gcc on win32.

Really we are only interested in Cache line information which can be found using 0x80000006 code and its lower 8 bits returned from ECX register.

#include 
#include 
#include 

int MASK_LSB_8 = 0xFF;

void int2bin(int val) {
	char buffer[33];
	itoa(val, buffer, 2);
	printf("binary: %s\n", buffer);
}

// CPUID instruction takes no parameters as CPUID implicitly uses the EAX register.
// The EAX register should be loaded with a value specifying what information to return
void cpuinfo(int code, int *eax, int *ebx, int *ecx, int *edx) {
	__asm__ volatile(
			"cpuid;" //  call cpuid instruction
			:"=a"(*eax),"=b"(*ebx),"=c"(*ecx), "=d"(*edx)// output equal to "movl  %%eax %1"
			:"a"(code)// input equal to "movl %1, %%eax"
			//:"%eax","%ebx","%ecx","%edx"// clobbered register
	);
}

int main() {
	int eax = 0, ebx = 0, ecx = 0, edx = 0;
	//CPUID(0): Basic information
	cpuinfo(0x0, &eax, &ebx, &ecx, &edx);

	// check vendor [GenuineIntel, GenuntelineI] = ebx+ecx+edx
	char vendor[13] = { 0 };
	int identity_reg[3] = { ebx, ecx, edx };
	for (unsigned int i = 0; i < 3; i++) {
		for (unsigned int j = 0; j < 4; j++) {
			vendor[i * 4 + j] = identity_reg[i] >> (j * 8) & MASK_LSB_8;
		}
	}
	printf("\nVendor name = %s\n", vendor);

	//CPUID(0x80000000): Extended CPU information
	cpuinfo(0x80000000, &eax, &ebx, &ecx, &edx);
	int intelExtended = eax & MASK_LSB_8;
	printf("\nMax feature id = %d\n", intelExtended);
	if (intelExtended < 6) {
		printf("\nCache Extended Feature not supported");
		return 0;
	}
	// CPUID(0x800000006): Cache line information
	cpuinfo(0x80000006, &eax, &ebx, &ecx, &edx);
	// We are only interested in lower 8 bits
	printf("\nL2 Cache Size = %d\n", (ecx & MASK_LSB_8));
}

Here is the output from my machine.

Vendor name = GenuntelineI
Max feature id = 8
L2 Cache Size = 64

The following result can be verified by using cpu-z program.

  	L1 Data cache	4 x 32 KBytes, 8-way set associative, 64-byte line size
    	L1 Instruction cache	4 x 32 KBytes, 8-way set associative, 64-byte line size
    	L2 cache	4 x 256 KBytes, 8-way set associative, 64-byte line size
    	L3 cache	6 MBytes, 12-way set associative, 64-byte line size

References

Comments

3 responses to “Using ‘cpuid’ instructions to get cache line size”

  1. Ronald Avatar

    Hey Greg I got a chance to run through this code last night.

    Just to add to your arsenal of reference material: Art of assembly.
    http://www.planetpdf.com/codecuts/pdfs/aoa.pdf

  2. dcx3 Avatar
    dcx3

    “GenuntelineI” is invalid.
    GenuineIntel
    EBX:EDX:ECX
    🙂

  3. Joshua Studen Avatar
    Joshua Studen

    How do I use this to get L3 cache size? I can see it gives L2 cache size, but I have no idea how to change it to get L3.

Leave a Reply

Your email address will not be published. Required fields are marked *