KargeMedlem sedan juni 20003 inlägg Hej
Har fått ett tips om att använda API funktionerna
QueryPerformanceCounter
QueryPerformanceFrequency
för att mäta tid.
Hur jag skall anropa dem och använda dem vej jag ej.
Skulle vilja ha hjälp med att implementera dessa
funktioner i min källkod.
Tack på förhand.
Micael
SweyMedlem sedan apr. 20003 971 inlägg Skapa en LARGE_INTEGER och peka till den när du anropar till någon av funktionerna eftersom enda parametern är en peka till LARGE_INTEGER.
Inte för att jag förstår varför du vill anropa funktionerna. Om du vill mäta tid kan du använda GetTickCount som är betydligt enklare. Vad är det för tid du vill mäta?
------------------
/mvh Swey
Programmera PHP
KargeMedlem sedan juni 20003 inlägg Tack för ditt svar. Men hur skapar jag en Large-Integer?
Jag har tittat lite på denna funktionshantering i VB och C språk.
I båda språken delar man upp variabeln i två delar och i VB kontrollerar man om den minst signifikanta delen av variabeln är negativ.
Är osäker på hur jag skall gå tillväga med variabeluppdelningen och även hur jag skall typa en Large_integer.
Dessa funktioner skall jag använda för precitionsmätning av inkommande pulser.
Med andra ord precitionstidbas.
WiNNeMedlem sedan maj 2000192 inlägg Föreslår att du använder en vanlig double som variabel.
Följande exempel har ett formulär med en vanlig knapp på bara och visar antalet millisekunder som gått sedan programmet startade, glöm inte att lägga till eventen.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
test,test2 : double;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
test:=gettickcount();
showmessage( floattostr((test-test2)) );
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
test2:=gettickcount();
end;
end.
------------------
------------------------
winne.net
jtMedlem sedan juni 2000350 inlägg Skälet till använda QueryPerformance är väl pga den högre noggranheten.
var
StartQPC, StopQPC, QPFrequency: TLargeInteger;
StartGTC, StopGTC: DWord;
Tid: Extended;
begin
//QueryPerformance
QueryPerformanceFrequency(QPFrequency);
QueryPerformanceCounter(StartQPC);
beep;
QueryPerformanceCounter(StopQPC);
Tid := (StopQPC.Quadpart - StartQPC.QuadPart) / QPFrequency.QuadPart;
Label1.Caption := 'Tid : ' + FloatTostr(Tid) + ' sekunder';
//GetTickCount
StartGTC := GetTickCount;
beep;
StopGTC := GetTickCount;
Tid := (StopGTC - StartGTC) / 1000 ;
Label2.Caption := 'Tid : ' + FloatTostr(Tid) + ' sekunder';
end;
Koden skriven för Delphi3
WiNNeMedlem sedan maj 2000192 inlägg Fungerar inte med .Quadpart i Delphi5 så jag vet inte var du fått det ifrån. Möjligt nånting som försvann till D5, hur nu en vanlig Int64 kan ha några särskillda propertys...?
Hur ofta behövs sån nogrannhet i tidsmätningar. millisekunder räcker ju långt för 3d-spel. Där är det viktigare att själva funktionen som mäter är snabbare.
------------------
winne.net
jtMedlem sedan juni 2000350 inlägg Som jag skrev var koden för Delphi 3.
I D3 finns inte int64 utan man kan använda TLargeInteger, som inte har några propeties utan är ett record(som du kan hitta i windows uniten). Int64 kom väl i D4.
Orkar inte leta efter info om hur stor skillnaden är mellan QueryPerformanceCounter och GetTickCount är. Men har för mig att GetTickCount noggranhet kan skiftar mellan +-10ms ibland upp till 55 ms.
Tror knappast man använder GetTickCount i proffisionela spel, någon som vet hur man brukar göra?.
Sedan frågades det efter hur QPC skulle implementeras.
Nu kan det ju vara ganska svårt att få bra noggranhet i windows av helt andra skäl
WiNNeMedlem sedan maj 2000192 inlägg Kolla i dokumentationen kring DirectX så ser du att GetTickCount används flitigt. Nogrannheten är inte +-10ms utan +-0,5ms då den bara ger antalet millisekunder mellan anropen.
Men du har rätt i att frågan gällde QPC och därför är det säkert nog tjatat om vilket sätt som är bäst. QPC har betydligt bättre nogrannhet men tar processorn längre tid att räkna fram så vill man ha snabba svar (vanligt i snabba applikationer som t.ex. spel) är QPC för långsamt.
Kollade i koden för TLargeInteger (i Delphi5) och den pekar numera bara på en vanlig int64, antar att den finns kvar för att vara någorlunda bakåtkompatibel även om jag blev förvånad att D5 inte kunde kompilera D3 kod (brukar vara tvärtom).
------------------
winne.net
jtMedlem sedan juni 2000350 inlägg Vet inte om jag tänker rätt men kör du denna kod så verkar inte noggranheten vara +-0,5ms.
På min dator varierar resultatet från 3 - 20 ms. Kanske ett tanke fel (iden till koden kom från MS sidor).
var
Count1, Count2: DWord;
Loops: Integer;
begin
Loops := 0;
Count1 := GetTickCount();
repeat
Count2 := GetTickCount();
inc(Loops);
until Count1 <> Count2;
ShowMessage('C2-C1: ' + IntToStr(Count2-Count1) + #10#13 +
'Loops: ' + IntToStr(Loops));
end;
Inte min mening att detta eller föregående inlägg skulle/ska uppfattas som tjat.
Bara roligt att diskutera saker som jag tycker är svårt/avancerat.
WiNNeMedlem sedan maj 2000192 inlägg Håller med, kul att det finns flera här i Delphi tråden som kan nånting och verkar vara vettigt folk 
I mitt Tetris spel (finns på www.winne.net) använder jag, precis som alla andra källkoder över spel jag sett, GetTickCount för att hålla ordning på sakerna i main loopen.
Här är ett urklipp ur den:
//////////////////////////////////////////////////////////////////////////
// WinMain, Initialization, message loop
///////////////////////////////////////////////////////////////////////////
Var aMSG : MSG;
i : integer;
KEYBOARD_DOWN: boolean;
Begin
If InitApp(GetModuleHandle(nil), SW_SHOW) <> DD_OK then Exit;
thisTickCount := GetTickCount;
lastTickCount := ThisTickCount;
[Snip]
While True do
Begin
If PeekMessage(aMsg, 0, 0, 0, PM_NOREMOVE) then
Begin
If not GetMessage(aMsg, 0, 0, 0) then Exit;
TranslateMessage(aMsg);
DispatchMessage(aMsg);
End
Else If (g_bActive) then
Begin
thisTickCount := GetTickCount;
If Mode=GAMEMODE Then
Begin
if (thisTickCount - lastTickCount ) \> TIMER_RATE Then
Begin
lastTickCount := ThisTickCount;
If Check_Collision(test,0,20) Then
begin
Konvert;
\[Snip\]
UpdateFrame;
End;
End
Else
Begin
WaitMessage;
End;
End;
End.
Tror inte att om inte GetTickCount skulle varit noggrann att det fungerat bra i spel då det i så fall hade varit hackit eller i alla fall oregelbundet.
Då övergången till Exclusive DirectX mode ger bättre kontroll över processorn
(windows stör inte så mycket) så fungerar GetTickCount utmärkt. När man kör ditt exempel i windows så kan ju windows själv ibland få för sig att göra andra saker mitt i körningen och därför ge olika resultat hela tiden.
------------------
winne.net
jtMedlem sedan juni 2000350 inlägg Koden i mitt exempel kommer från Ms Knowledge base för att räkna ut noggranheten på dylika API.
Använder inte Direct X så jag har ingen aning om detta. Men nu pratade vi om tidsmättning i windows ;-).
jtMedlem sedan juni 2000350 inlägg Nu börjar jag faktisk bli tjatig ;-).
Men detta är nog den enda delphi tråd på WF som jag lärt mig något från.
"
The GetCurrentTime() and GetTickCount() functions are identical. Each returns the
number of milliseconds (+/- 55 milliseconds) since the user started Windows, and the
return value of each function is declared to be a DWORD.
"
http://support.microsoft.com/support/kb/articles/Q45/7/02.ASP
WiNNeMedlem sedan maj 2000192 inlägg Hmmm, måste helt enkelt vara så att det är annorlunda när man kör i DirectX mode då. Med sådan dålig noggrannhet skulle nog inte mitt spel fungera så värst bra...
Ladda hem och testa det, vetja...
(www.winne.net)
Jag e riktigt nöjd med det :)
------------------
winne.net
jtMedlem sedan juni 2000350 inlägg Ska testa tetrix i morgon på jobbet :).
Där jag har lite snabbare uppkopling.
Tror knappast min gammla dator(P133 32MB :( ) har directx 7.
WiNNeMedlem sedan maj 2000192 inlägg Det går ju alltid att lägga in DX7 även på en såpass gammal dator. Tänk på om du kör det på jobb att DX7 inte finns till NT4 (det vanligaste jobb-OSet) och därför funkar inte heller mitt spel för NT4. Mycket Nöje... :)
ps. jag vet att det blev stort, c:a 9MB, men musiken är en MP3 låt som jag ville behålla i bra kvalité så då var det värt det... Och innan ni börjar (an)klaga på att låten är riktig med en visserligen relativt okänd artist (för mig iaf) så är det en kraftigt re-mixad version gjord av en polare och det gör det faktiskt hur lagligt som helst. :)
------------------
winne.net
WiNNeMedlem sedan maj 2000192 inlägg Hmmm, lite off-topic där visst...
Vi kanske ska starta en egen diskussionstråd Jt ??? :)
------------------
winne.net
KargeMedlem sedan juni 20003 inlägg Hej.
Tack allesammans för era inlägg. Jag lyckades lösa problemet med QueryPerformanse som tidsmätare. Använder mig av INT64 variabel.Denna tidsmätning skall inte vara till spel utan mätning av frekvens in på parallellporten. Detta för styr & reglerändamål. Funktionen GetTickCount är ej tillräcklig för denna mätning. Frågan är om funktionen QueryPerformanse
tillsammans med Win9x har tillräcklig precision. Har provat med polling vilket ej givit tillfredställande resultat. Håller på att lära mig assembler och därmed kunna använda mig utav hårvaruinterupts.