About QueryPerformanceCounter and it's own set of problems..
http://support.microsoft.com/default...EN-US;Q274323&
http://www.gamedev.net/community/for...opic_id=357026
Do you still claim that gettickcount is imprecise? think again.
About QueryPerformanceCounter and it's own set of problems..
http://support.microsoft.com/default...EN-US;Q274323&
http://www.gamedev.net/community/for...opic_id=357026
Do you still claim that gettickcount is imprecise? think again.
This is my game project - Top Down City:
http://www.pascalgamedevelopment.com...y-Topic-Reboot
My OpenAL audio wrapper with Intelligent Source Manager to use unlimited:
http://www.pascalgamedevelopment.com...source+manager
Its not a matter of claiming or thinking, its a matter of facts.
GetTickCount may not suffer from bugs in hardware but its resolution is definitely 1ms,
which is far too crude to time function calls (especially in the way arthurprs does).
new code
[pascal]program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
Math;
type
TPoint = record
x,y : Single;
end;
TPoint4 = array[0..3] of TPoint;
procedure Test1(const a, b: TPoint4);
var
c : Single;
begin
c := a[0].x + b[3].x;
Power(c,2);
end;
procedure Test2(const a, b: TPoint4); stdcall;
var
c : Single;
begin
c := a[0].x + b[3].x;
Power(c,2);
end;
procedure Test3(const a, b: TPoint4); cdecl;
var
c : Single;
begin
c := a[0].x + b[3].x;
Power(c,2);
end;
const
s = 10000000;
var
a, b: TPoint4;
t1, t2, fq, n: Int64;
begin
QueryPerformanceFrequency(fq);
n := 0;
QueryPerformanceCounter(t1);
repeat
Test3(a, b);
Inc(n);
QueryPerformanceCounter(t2);
until t2 >= t1 + s;
Writeln(n);
n := 0;
QueryPerformanceCounter(t1);
repeat
Test2(a, b);
Inc(n);
QueryPerformanceCounter(t2);
until t2 >= t1 + s;
Writeln(n);
n := 0;
QueryPerformanceCounter(t1);
repeat
Test1(a, b);
Inc(n);
QueryPerformanceCounter(t2);
until t2 >= t1 + s;
Writeln(n);
n := 0;
QueryPerformanceCounter(t1);
repeat
Test3(a, b);
Inc(n);
QueryPerformanceCounter(t2);
until t2 >= t1 + s;
Writeln(n);
n := 0;
QueryPerformanceCounter(t1);
repeat
Test2(a, b);
Inc(n);
QueryPerformanceCounter(t2);
until t2 >= t1 + s;
Writeln(n);
n := 0;
QueryPerformanceCounter(t1);
repeat
Test1(a, b);
Inc(n);
QueryPerformanceCounter(t2);
until t2 >= t1 + s;
Writeln(n);
Writeln('end'); Readln;
end.[/pascal]
fastcall is really faster (difference is VERY small)
"1632286
1548087
1678139
1564791
1637757
1672389
end"
From brazil (:
Pascal pownz!
Your results are similar to my own. All calling conventions are equally fast
However most of your bench time is taken by the loop, not the call.
You're not likely to notice much of a difference in most cases.
Standard calls place all the parameters on the stack when you call the function, then pops them when you return. With a register (fastcall) function, it places the first three (I believe) parameters into CPU registers, saving you from the overhead of creating the stack frame if you use 3 or less parameters.
Thing is, PUSH and POP are very fast operations anyway, and a lot of Delphi calls will use more than 3 parameters. Any object method passes "self" as an implicit parameter, and constructors pass a hidden boolean variable that's needed for inheritance. And since most things in Delphi use objects, any method call with more than 2 parameters declared will create a stack frame.
That having been said, even a small performance gain is worth taking, on general principle, and if you're using a function in an inner loop, the sort of thing that gets called all the time in your program, especially if it's a very short function, you'll want to make sure it's declared register and has a short enough parameter list to benefit from it, since those few processor cycles can add up over a few million calls.
Bookmarks