Встретились четыре компьютерщика, а бутылка ВОДКИ только одна. Мало! Долго недумая взяли и разогнали её до 400.
Если Вам необходимо не только "вычислить" частоту процессора, а и узнать о
процессоре как можно больше, пожалуйста, пользуйтесь следующим модулем:
unit ExpandCPUInfo;
interfacetype
TCPUInfo = packedrecord
IDString : array [0..11] of Char;
Stepping : Integer;
Model : Integer;
Family : Integer;
FPU,
VirtualModeExtensions,
DebuggingExtensions,
PageSizeExtensions,
TimeStampCounter,
K86ModelSpecificRegisters,
MachineCheckException,
CMPXCHG8B,
APIC,
MemoryTypeRangeRegisters,
GlobalPagingExtension,
ConditionalMoveInstruction,
MMX : Boolean;
SYSCALLandSYSRET,
FPConditionalMoveInstruction,
AMD3DNow : Boolean;
CPUName : String;
end;
{информация об идентификации процессора}function ExistCPUID:Boolean;
function CPUIDInfo(out info: TCPUInfo):Boolean;
{инф-я о технологии процессора}function ExistMMX:Boolean;
function Exist3DNow:Boolean;
function ExistKNI:Boolean;
{------------------------}procedure EMMS;
procedure FEMMS;
procedure PREFETCH(p: Pointer); register;
implementationfunction ExistCPUID : Boolean;
asm
pushfd
pop eax
mov ebx, eax
xor eax, 00200000h
push eax
popfd
pushfd
pop ecx
mov eax,0
cmp ecx, ebx
jz @NO_CPUID
inc eax
@NO_CPUID:
end;
function CPUIDInfo(out info: TCPUIDInfo):Boolean;
function ExistExtendedCPUIDFunctions:Boolean;
asm
mov eax,080000000h
db $0F,$A2
end;
var
name : array [0..47] of Char;
p : Pointer;
beginif ExistCPUID thenasm
jmp @Start
@BitLoop:
mov al,dl
and al,1
mov [edi],al
shr edx,1
inc edi
loop @BitLoop
ret
@Start:
mov edi,info
mov eax,0
db $0F,$A2
mov [edi],ebx
mov [edi+4],edx
mov [edi+8],ecx
mov eax,1
db $0F,$A2
mov ebx,eax
and eax,0fh;
mov [edi+12],eax;
shr ebx,4
mov eax,ebx
and eax,0fh
mov [edi+12+4],eax
shr ebx,4
mov eax,ebx
and eax,0fh
mov [edi+12+8],eax
add edi,24
mov ecx,6
call @BitLoop
shr edx,1
mov ecx,3
call @BitLoop
shr edx,2
mov ecx,2
call @BitLoop
shr edx,1
mov ecx,1
call @BitLoop
shr edx,7
mov ecx,1
call @BitLoop
mov p,edi
end;
if (info.IDString = 'AuthenticAMD') and ExistExtendedCPUIDFunctions thenbeginasm
mov edi,p
mov eax,080000001h
db $0F,$A2
mov eax,edx
shr eax,11
and al,1
mov [edi],al
mov eax,edx
shr eax,16
and al,1
mov [edi+1],al
mov eax,edx
shr eax,31
and al,1
mov [edi+2],al
lea edi,name
mov eax,0
mov [edi],eax
mov eax,080000000h
db $0F,$A2
cmp eax,080000004h
jl @NoString
mov eax,080000002h
db $0F,$A2
mov [edi],eax
mov [edi+4],ebx
mov [edi+8],ecx
mov [edi+12],edx
add edi,16
mov eax,080000003h
db $0F,$A2
mov [edi],eax
mov [edi+4],ebx
mov [edi+8],ecx
mov [edi+12],edx
add edi,16
mov eax,080000004h
db $0F,$A2
mov [edi],eax
mov [edi+4],ebx
mov [edi+8],ecx
mov [edi+12],edx
@NoString:
end;
info.CPUName:=name;
endelsewith info dobegin
SYSCALLandSYSRET:=False;
FPConditionalMoveInstruction:=False;
AMD3DNow:=False;
CPUName:='';
end;
Result:=ExistCPUID;
end;
function ExistMMX:Boolean;
var
info : TCPUIDInfo;
beginif CPUIDInfo(info) then
Result:=info.MMX
else
Result:=False;
end;
function Exist3DNow:Boolean;
var
info : TCPUIDInfo;
beginif CPUIDInfo(info) then
Result:=info.AMD3DNow
else
Result:=False;
end;
function ExistKNI:Boolean;
begin
Result:=False;
end;
procedure EMMS;
asm
db $0F,$77
end;
procedure FEMMS;
asm
db $0F,$03
end;
procedure PREFETCH(p: Pointer); register;
asm// PREFETCH byte ptr [eax]end;
end.
Эта единица Delphi обеспечивает функции для получения информации о процессоре (Central Processing Unit) и его возможностях.
Единица определяет несколько функций:
ExistCPUID: Возвращает True, если процессор поддерживает инструкцию CPUID.
CPUIDInfo(out info: TCPUIDInfo): Получает информацию о процессоре, включая строку ID, номер шага, номер модели, номер семейства и другие детали. Функция заполняет запись TCPUIDInfo полученными данными.
ExistMMX, Exist3DNow, ExistKNI: Проверяет, поддерживает ли процессор инструкции MMX (Multimedia Extension), 3D Now!, или KNI (Kernel Normal Interface) соответственно.
Единица также определяет несколько процедур:
EMMS: Эмулирует вызов системы управления памятью.
FEMMS: Очищает кэш EMMS.
PREFETCH(p: Pointer): Предзагружает данные из памяти в кэш процессора. Процедура принимает указатель на данные как аргумент.
Единица использует inline-ассемблер для доступа к инструкции CPUID и другим низкоуровневым функциям процессора.
Некоторые наблюдения и предложения:
Единица quite сложна, с множеством функций и процедур, взаимодействующих друг с другом.
Запись TCPUIDInfo определена в единице, но не ясно, почему она имеет столько полей. Могло бы быть полезно разбить запись на более маленькие, конкретные записи или классы.
Inline-ассемблер quite плотный и может быть трудным для чтения и поддержки. Рекомендуется вынести ассемблер в отдельные функции или процедуры, каждая с четким предназначением.
В единице используются несколько магических чисел (например, 080000000h, 00200000h). Могло бы быть полезно определить константы для этих значений.
Функция ExistKNI всегда возвращает False. Если это преднамеренное, рекомендуется добавить комментарий, объясняющий почему.
В целом, единица appears to provide comprehensive set of functions and procedures for working with CPU features in Delphi. However, it may benefit from some refactoring to improve readability, maintainability and performance.
Получение информации о процессоре позволяет определить его модель, технологию, наличие дополнительных функций и других параметров.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.