Как найти скорость процессора?

=== Как найти скорость процессора? ===
Пример взят из рассылки: СообЧА. Программирование на Delphi (http://Subscribe.Ru/catalog/comp.soft.prog.delphi2000)
function GetCPUSpeed: Double;
const
 DelayTime = 500;
var
 TimerHi: DWORD;
 TimerLo: DWORD;
 PriorityClass: Integer;
 Priority: Integer;
begin
 PriorityClass := GetPriorityClass(GetCurrentProcess);
 Priority := GetThreadPriority(GetCurrentThread); 
 SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
 SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
 Sleep(10);
 asm
 DW 310Fh // rdtsc
 MOV TimerLo, EAX
 MOV TimerHi, EDX
 end;
 Sleep(DelayTime);
 asm
 DW 310Fh // rdtsc
 SUB EAX, TimerLo
 SBB EDX, TimerHi
 MOV TimerLo, EAX
 MOV TimerHi, EDX
 end;
 SetThreadPriority(GetCurrentThread, Priority);
 SetPriorityClass(GetCurrentProcess, PriorityClass);
 Result := TimerLo / (1000.0 * DelayTime);
end;
// Usage ...
LabelCPUSpeed.Caption := Format('CPU speed: %f MHz', [GetCPUSpeed]);
Source: Взято с Vingrad.ru http://forum.vingrad.ru
ID: 01415
----
function GetCPUSpeed: real; 
 function IsCPUID_Available: Boolean; assembler; register; 
 asm 
 PUSHFD { прямой доступ к флагам невозможен, только через стек }
 POP EAX { флаги в EAX } 
 MOV EDX,EAX { сохраняем текущие флаги }
 XOR EAX,$200000 { бит ID не нужен }
 PUSH EAX { в стек } 
 POPFD { из стека в флаги, без бита ID } 
 PUSHFD { возвращаем в стек }
 POP EAX { обратно в EAX } 
 XOR EAX,EDX { проверяем, появился ли бит ID }
 JZ @exit { нет, CPUID не доступен }
 MOV AL,True { Result=True } 
 @exit: 
 end; 
 function hasTSC: Boolean; 
 var 
 Features: Longword; 
 begin 
 asm 
 MOV Features,0 { Features = 0 } 
 PUSH EBX 
 XOR EAX,EAX 
 DW $A20F 
 POP EBX 
 CMP EAX,$01 
 JL @Fail 
 XOR EAX,EAX 
 MOV EAX,$01 
 PUSH EBX 
 DW $A20F 
 MOV Features,EDX 
 POP EBX 
 @Fail: 
 end; 
 hasTSC := (Features and $10) <> 0; 
 end; 
const 
 DELAY = 500; 
var 
 TimerHi, TimerLo: Integer; 
 PriorityClass, Priority: Integer; 
begin 
 Result := 0; 
 if not (IsCPUID_Available and hasTSC) then Exit; 
 PriorityClass := GetPriorityClass(GetCurrentProcess); 
 Priority := GetThreadPriority(GetCurrentThread); 
 SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS); 
 SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL); 
 SleepEx(10, FALSE); 
 asm 
 DB $0F { $0F31 op-code for RDTSC Pentium инструкции } 
 DB $31 { возвращает 64-битное целое (Integer) } 
 MOV TimerLo,EAX 
 MOV TimerHi,EDX 
 end; 
 SleepEx(DELAY, FALSE); 
 asm 
 DB $0F { $0F31 op-code для RDTSC Pentium инструкции } 
 DB $31 { возвращает 64-битное целое (Integer) } 
 SUB EAX,TimerLo 
 SBB EDX,TimerHi 
 MOV TimerLo,EAX 
 MOV TimerHi,EDX 
 end; 
 SetThreadPriority(GetCurrentThread, Priority); 
 SetPriorityClass(GetCurrentProcess, PriorityClass); 
 Result := TimerLo / (1000 * DELAY); 
end;
Source: Взято из http://forum.sources.ru
ID: 01416
----
const 
 ID_BIT = $200000; // EFLAGS ID bit 
function GetCPUSpeed: Double; 
const 
 DelayTime = 500; 
var 
 TimerHi, TimerLo: DWORD; 
 PriorityClass, Priority: Integer; 
begin 
 try 
 PriorityClass := GetPriorityClass(GetCurrentProcess); 
 Priority := GetThreadPriority(GetCurrentThread); 
 SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS); 
 SetThreadPriorit(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL); 
 Sleep(10); 
 asm 
 dw 310Fh // rdtsc 
 mov TimerLo, eax 
 mov TimerHi, edx 
 end; 
 Sleep(DelayTime); 
 asm 
 dw 310Fh // rdtsc 
 sub eax, TimerLo 
 sbb edx, TimerHi 
 mov TimerLo, eax 
 mov TimerHi, edx 
 end; 
 SetThreadPriority(GetCurrentThread, Priority); 
 SetPriorityClass(GetCurrentProcess, PriorityClass); 
 Result := TimerLo / (1000.0 * DelayTime); 
 except
 end; 
end; 
procedure TForm1.Button1Click(Sender: TObject); 
var
 cpuspeed: string; 
begin 
 cpuspeed := Format('%f MHz', [GetCPUSpeed]); 
 edit1.text := cpuspeed; 
end;
Source: Взято из http://forum.sources.ru
ID: 01417
----
function RdTSC : int64; register; 
asm 
 db $0f, $31 
end; 
function GetCyclesPerSecond : int64; 
var 
 hF, T, et, sc : int64; 
begin 
 QueryPerformanceFrequency(hF); // HiTicks / second 
 QueryPerformanceCounter(T); // Determine start HiTicks 
 et := T + hF; // (Cycles are passing, but we can still USE them!) 
 sc := RdTSC; // Get start cycles 
 repeat // Use Hi Perf Timer to loop for 1 second 
 QueryPerformanceCounter(T); // Check ticks NOW 
 until (T >= et); // Break the moment we equal or exceed et 
 Result := RdTSC - sc; // Get stop cycles and calculate result 
end;
Source: Взято из http://forum.sources.ru
ID: 01418
----
Данная тема уже обсуждалась, но у меня есть своя реализация сабжа. Начиная с Pentium MMX, Intel ввели в процессор счетчик тактов на 64 бита (Присутствуэт точно и в К6). Для того чтобы посотреть на его содержание, была введена команда "rdtsc" (подробное описание в интеловской мануале). Эту возможность можно использовать для реализации сабжа. Посоку Делфя не вкурсе насчет rdtsc, то пришлось юзать опкод (0F31). Привожу простенький примерчик юзания, Вы уж извините - немножко кривоват получился, да и ошибка компалера какая-то вылезла :( (V4 Bld5.104 Upd 2). Кому интересно, поделитесь своими соображениями по этому поводу. Особенно интерисует работа в режиме когда меняется частота процессора (Duty Cycle, StandBy). 
// (C) 1999 ISV
unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics,
 Controls, Forms,Dialogs, StdCtrls, Buttons, ExtCtrls;
type
 TForm1 = class(TForm)
 Label1: TLabel;
 Timer1: TTimer;
 Label2: TLabel;
 Label3: TLabel;
 Button1: TButton;
 Button2: TButton;
 Label4: TLabel;
 procedure Timer1Timer(Sender: TObject);
 procedure FormActivate(Sender: TObject);
 procedure Button1Click(Sender: TObject);
 procedure Button2Click(Sender: TObject);
 public
 { Public declarations }
 Counter: Integer; // Счетчик срабатывания таймера
 Start: Int64; // Начало роботы
 Previous: Int64; // Предыдущее значение
 PStart, PStop: Int64; // Для примера выч. времени
 CurRate: Integer; // Текущая частота проца
 function GetCPUClick: Int64;
 function GetTime(Start, Stop: Int64): Double;
 end;
var
 Form1: TForm1;
implementation
{$R *.DFM}
// Функция работает на пнях ММХ или выше а
// также проверялась на К6
function TForm1.GetCPUClick: Int64;
begin
 asm
 db 0fh,31h
 // Опкод для команды rdtsc
 // mov dword ptr result,eax
 // mov dword ptr result[4],edx
 end;
 // Не смешно :(. Без ?той штуки
 // Компайлер выдает Internal error C1079
 Result := Result;
end;
// Время в секундах между старт и стоп
function TForm1.GetTime(Start, Stop: Int64): Double;
begin
 try
 Result := (Stop-Start)/CurRate
 except
 Result := 0;
 end;
end;
// Обработчик таймера считает текущую частоту, выводит ее, а также
// усредненную частоту, текущий такт с момента старта процессора.
// При постоянной частоте процессора желательно интервал братьпобольше
// 1-5с для точного прощета частоты процессора.
procedure TForm1.Timer1Timer(Sender: TObject);
var
 i: Int64;
begin
 i := GetCPUClick;
 if Counter = 0 then
 Start := i
 else
 begin
 Label2.Caption := Format('Частота общая:%2f', [(i-Start)/(Counter*Timer1.Interval*1000)]);
 Label3.Caption := Format('Частота текущая:%2f', [(i-Previous)/(Timer1.Interval*1000)]);
 CurRate := Round(((i-Previous)*1000)/(Timer1.Interval));
 end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
 PStart := GetCPUClick;
end;
// Останавливаем отсчет времени и показуем соко
// прошло секунд
procedure TForm1.Button2Click(Sender: TObject);
begin
 PStop := GetCPUClick;
 Label4.Caption := Format('Время между нажатиями:%gсек', [GetTime(PStart, PStop)]);
end;
end.
Проверялось под еНТями на Пне 2 333. 
Source: http://delphiworld.narod.ru/
ID: 01419
----
uses registry;
function GetCpuMhz: Word;
begin
 with TRegistry.Create do
 begin
 RootKey := HKEY_LOCAL_MACHINE;
 OpenKey('\hardware\description\system\centralprocessor\0\', False);
 Result := ReadInteger('~mhz');
 Free;
 end;
end;
Source: http://delphiworld.narod.ru/
ID: 01420