09 julio 2007

Averiguar el nombre del procesador y su velocidad

El registro de Windows suele almacenar gran cantidad de información no sólo de la configuración de los programas instalados, sino también el estado real del hardware de nuestro PC.

En esta ocasión vamos a leer el nombre del procesador y su velocidad desde nuestro programa. Antes de nada añadimos a uses:

uses
Windows, Messages, ..., Registry;

La siguiente función nos devuelve el nombre del procesador:

function NombreProcesador: string;
var
Registro: TRegistry;
begin
Result := '';
Registro := TRegistry.Create;

try
Registro.RootKey := HKEY_LOCAL_MACHINE;

if Registro.OpenKey( '\Hardware\Description\System\CentralProcessor\0', False ) then
Result := Registro.ReadString( 'Identifier' );
finally
Registro.Free;
end;
end;

Y esta otra nos da su velocidad (según la BIOS y el fabricante):

function VelocidadProcesador: string;
var
Registro: TRegistry;
begin
Registro := TRegistry.Create;
try
Registro.RootKey := HKEY_LOCAL_MACHINE;

if Registro.OpenKey( 'Hardware\Description\System\CentralProcessor\0', False ) then
begin
Result := IntToStr( Registro.ReadInteger( '~MHz' ) ) + ' MHz';
Registro.CloseKey;
end;
finally
Registro.Free;
end;
end;

Hay veces que dependiendo del procesador y del multiplicador de la BIOS casi nunca coincide la velocidad real que nos da Windows con la de verdad (sobre todo en procesadores AMD). Aquí tenemos otra función que calcula en un segundo la velocidad real del procesador con una pequeña rutina en ensamblador:

function CalcularVelocidadProcesador: Double;
const
Retardo = 500;
var
TimerHi, TimerLo: DWORD;
ClasePrioridad, Prioridad: Integer;
begin
ClasePrioridad := GetPriorityClass( GetCurrentProcess );
Prioridad := GetThreadPriority( GetCurrentThread );

SetPriorityClass( GetCurrentProcess, REALTIME_PRIORITY_CLASS );
SetThreadPriority( GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL );

Sleep( 10 );

asm
dw 310Fh
mov TimerLo, eax
mov TimerHi, edx
end;

Sleep( Retardo );

asm
dw 310Fh
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;

SetThreadPriority( GetCurrentThread, Prioridad );
SetPriorityClass( GetCurrentProcess, ClasePrioridad );

Result := TimerLo / ( 1000 * Retardo );
end;

Nos devuelve el resultado en una variable double, donde que podríamos sacar la información en pantalla de la siguiente manera:

ShowMessage( Format( 'Velocidad calculada: %f MHz', [CalcularVelocidadProcesador] ) );

Pruebas realizadas en Delphi 7.

Publicidad