[fpc-devel] AMD & Intel CPUCount (was: Feature announcement: Extension of TThread's interface)
Ewald
ewald at yellowcouch.org
Thu Dec 27 23:06:41 CET 2012
Right, since the /proc/cpuinfo (a) is not available on many platforms
and (b) has no standard output format, I decided to fix the half done
CPUID approach. Here it goes (note: don't shoot me if my assembly is a
bit weird, I've only learned part of it by experimenting):
[see below]
For time being there are only two CPU kinds supported (GenuineIntel and
AuthenticAMD), in other cases it returns the # of logical CPU's. Feel
free to extend the code with other CPU ID's ;-)
Oh, and the important part: The function has been tested on a Core 2 Duo
and an Intel i7, and works correctly. If someone would be so kind to
test it on some other CPU's that would be great! [I'm not 100% of the
hexadecimal of `AuthenticAMD` you see]
program cpucount;
{$mode objfpc}
{$asmmode att}
Function GetCores: LongWord;
Begin
Asm
//Vendor ID
MOV $0, %eax
MOV $0, %ecx
CPUID
// ?= GenuineIntel
CMP $0x756e6547, %ebx
JNE .LnotGenuineIntel
CMP $0x49656e69, %edx
JNE .LnotGenuineIntel
CMP $0x6c65746e, %ecx
JNE .LnotGenuineIntel
MOV $4, %eax
MOV $0, %ecx
CPUID
SHR $26, %eax
AND $0x3F, %eax
ADD $1, %eax
MOV %eax, __RESULT
JMP .LReturn
.LnotGenuineIntel:
// ?= AuthenticAMD
CMP $0x68747541, %ebx
JNE .LnotAuthenticAMD
CMP $0x69746e65, %edx
JNE .LnotAuthenticAMD
CMP $0x444d4163, %ecx
JNE .LnotAuthenticAMD
MOV $0x80000008, %eax
MOV $0, %ecx
CPUID
AND $0xFF, %ecx
ADD $1, %ecx
MOV %ecx, __RESULT
JMP .LReturn
.LnotAuthenticAMD:
//Return #logical CPU's
MOV $1, %eax
MOV $0, %ecx
CPUID
SHR $16, %ebx
AND $0xFF, %ebx
MOV %ebx, __RESULT
.LReturn:
End ['eax', 'ebx', 'ecx', 'edx'];
End;
Begin
Writeln('#CPU cores: ', GetCores);
End.
--
Ewald
More information about the fpc-devel
mailing list