Avatar billede allan5991 Nybegynder
03. oktober 2001 - 11:04 Der er 18 kommentarer

millisekunder i delphi

Jeg har skrevet nogle rutiner som jeg gerne vil teste tidsforbruget på.
Jeg har prøvet med funktionerne NOW og GETTICKCOUNT, men de returnerer kun
hundrededele sekunder 10,20,30 o.s.v.
Hvordan løser jeg dette problem ?
Avatar billede borrisholt Novice
03. oktober 2001 - 11:05 #1
Prøv med QueryPerformance funktionerne ...

Jens B
Avatar billede unclebug Nybegynder
03. oktober 2001 - 11:06 #2
QueryPerformanceCounter og QueryPerformanceFrequency. De giver ultra præcis timing.
Avatar billede borrisholt Novice
03. oktober 2001 - 11:07 #3
Ellers så prøv den her .. Så kan du få det ud i Klok cycles :

unit Unit2;

interface

uses
Windows, SysUtils;

type
  TMeasurement = (Seconds, Cycles);
  TFastTime = class(TObject)
  private
    Frequency, StartTime, EndTime: Int64;
    RDTSC_START, RDTSC_STOP : Comp;
    FElapsedTime : String;
    fMeasurement : TMeasurement;
    Function GetTimeStamp : Int64;
  public
    Property ElapsedTime : String read FElapsedTime;
    Procedure Start(Measurement : TMeasurement = Seconds);
    Procedure Stop;
end;

implementation

function TFastTime.GetTimeStamp: Int64;
var
  TimeStamp : Record
    case byte of
      1 : (Whole: Int64);
      2 : (LO, HI : longint);
    end;
begin
  asm
    db $0F;
    db $31;
    mov [TimeStamp.LO], eax
    mov [TimeStamp.HI], edx
  end;
  Result:=TimeStamp.Whole;
end;

Procedure TFastTime.Start(Measurement : TMeasurement = Seconds);
begin
  fMeasurement := Measurement;
  if Measurement = Seconds then
  begin
    QueryPerformanceFrequency(Frequency);
    QueryPerformanceCounter(StartTime);
  end
  else
    RDTSC_START := GetTimeStamp;
end;

Procedure TFastTime.Stop;
begin
  if fMeasurement = Seconds then
  begin
    QueryPerformanceCounter(EndTime);
    FElapsedTime:= format(\'Seconds: %g\', [(EndTime - StartTime)/ Frequency]);
  end
  else
  begin
    RDTSC_STOP := GetTimeStamp;
    FElapsedTime:= format(\'Clock Cycles: %.0n\', [RDTSC_STOP - RDTSC_START]);
  end;
end;
end.



Jens B
Avatar billede martinlind Nybegynder
03. oktober 2001 - 11:13 #4
Hvad med DateTimeToTimeStamp(Now), TTimeStamp er ret præcis

/Martin
Avatar billede unclebug Nybegynder
03. oktober 2001 - 11:16 #5
Giver elapsed time i millisekunder, så præcist som en PC kan gøre det:

  TTime = class(TObject)
  public
    Stamp : Int64;
    procedure StartClock;
    function  GetElapsedTime: Integer;
  end;

implementation

procedure TTime.StartClock;
begin
  QueryPerformanceCounter(Stamp);
end;

function TTime.GetElapsedTime: Integer;
var
  NewTime : Int64;
  Freq    : Int64;
begin
  QueryPerformanceCounter(NewTime);
  QueryPerformanceFrequency(Freq);
  Result := Round((NewTime - Stamp) / (Freq / 1000));
end;
Avatar billede borrisholt Novice
03. oktober 2001 - 11:20 #6
unglebug :>> Ikke helt hvis du måler i Click  cycles og kender din præcise Clock frekvens så op når du højere nøjagtighed .... Min kalsse kan bruge begge dele ....

Jens B
Avatar billede unclebug Nybegynder
03. oktober 2001 - 11:25 #7
Jeg vil give dig ret i at din er lige så præcis, men det fåes ikke mere præcist end QueryPerformanceCounter. Din GetTimeStamp gør formentlig det samme som den, så jeg kan ikke se hvorfor det er nødvendigt at bruge Asm (ikke at jeg har noget imod det, Asm rules).

Det ER clockfrekvensen på cpu\'en der bruges. Jeg har rundet det af til millisekunder, for det er nemmere at relatere til, men den er langt mere præcis end det. Den aflæser direkte fra CPU\'en (virker kun på Pentium og nyere).

Avatar billede borrisholt Novice
03. oktober 2001 - 11:29 #8
unclebug >> De to klasser (din og min9 gør det samme hvis du altså beder min om at måle i sekunder .... Grunder til jeg bruger ASM er jeg også giver brugeren mulighed for at måle i clock cycles ... DET skal man bruge asm til

Jens B
Avatar billede martinlind Nybegynder
03. oktober 2001 - 11:33 #9
TTimeStamp har Millisec. så hvorfor alt det benarb. men at opfinde den dybe igen
Avatar billede unclebug Nybegynder
03. oktober 2001 - 11:36 #10
Borrisholt>> prøv det følgende:

Stamp1 : int64;
Stamp2 : int64;
Elapsed: int64;

QueryPerformanceCounter(Stamp1)
... do some stuff
QueryPerformanceCounter(Stamp2)

Elapsed := Stamp2 - Stamp1;

Faktisk er jeg ikke helt sikker på om det er clockcycles det tælles her, men det burde det være. Det er CPU\'ens interne tæller. Er det ikke muligt at det kode du har også virker på 486 m.m.? For det gør performancecounter ikke.
Avatar billede borrisholt Novice
03. oktober 2001 - 11:38 #11
Nej desvære så virker mit kode ikke på 486, i det den bruger asm instruktionen RDTSC som kun findes i Pentium og op efter ...

Jens B
Avatar billede unclebug Nybegynder
03. oktober 2001 - 11:38 #12
MartinLind>> Jeg tror ikke Now er mere præcis end GetTickCount, og det er jo den man ville bruge til at få en værdi i TTimeStamp.
Avatar billede martinlind Nybegynder
03. oktober 2001 - 11:44 #13
Det er spm. for hvis du kigger i hjælpen, så taler de om millisec. og hvad skulle man også med en DateTimeToTimeStamp hvis ikke du fik et brugbart resultat

/Martin
Avatar billede unclebug Nybegynder
03. oktober 2001 - 11:54 #14
Her kan du se præcisionen på TTimeStamp:

procedure TMainForm.Button6Click(Sender: TObject);
var i : integer;
    Val :array[0..9] of TDateTime;
    Stamp : TDateTime;
begin
  for i:=0 to 9 do begin
    Stamp := Now;
    repeat until Now > Stamp;
    Val[i] := Stamp;
  end;

  for i:=0 to 9 do begin
    Memo1.Lines.Add(inttostr(DateTimeToTimeStamp(Val[i]).Time));
  end;
end;

I min Win2K springer den 10ms., det samme som GetTickCount.
Avatar billede martinlind Nybegynder
03. oktober 2001 - 12:00 #15
Ok, ja så kan den jo ikke bruges
Avatar billede borrisholt Novice
03. oktober 2001 - 12:07 #16
Min unit TfastTime reagerer på omkring 4-500 Clock cycels ....


prøv det følgende test program :

To knapper og en label :

uses
  unit2;
var
  FastTime : TFastTime;
procedure TForm1.Button1Click(Sender: TObject);
begin
  FastTime.Start;
  FastTime.Stop;
  Label1.Caption := FastTime.ElapsedTime;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  FastTime.Start(Cycles);
  FastTime.Stop;
  Label1.Caption := FastTime.ElapsedTime;
end;

initialization
  FastTime := TFastTime.Create;
finalization
  FreeAndNil(FastTime);
end.

Jens B
Avatar billede borrisholt Novice
09. oktober 2001 - 08:59 #17
allan5991 >> sker der noget ?

Jens B
Avatar billede borrisholt Novice
16. oktober 2001 - 18:08 #18
Lukker du efter dig eller hvad ?

Jens B
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester