@TCH:Max esetleg úgy, hogy méri 10 másodpercig és a várt/mért különbségből számol egy offsetet. De akkor így a program inicializálása baromi sokáig fog tartani. Viszont vehetünk kisebb időszeletet is, maximum a mérés nem lesz annyira pontos. Én most átírtam a mérést:unit cusleep_lib;
interface
procedure cusleep(usec: longint);
procedure init_cusleep;
implementation
uses unix;
var
cusleep_time: longint;
procedure cusleep(usec: longint); assembler;
label l0;
asm
{$ifdef cpu386}
movl usec, %eax
movl cusleep_time, %ecx
mul %ecx
xorl %ecx, %ecx
l0:
incl %ecx
cmpl %eax, %ecx
jne l0
{$endif cpu386}
{$ifdef cpux86_64}
movl usec, %eax
movl cusleep_time, %ecx
mul %ecx
xorl %ecx, %ecx
l0:
incl %ecx
cmpl %eax, %ecx
jne l0
{$endif cpux86_64}
{$ifdef cpupowerpc}
ld r1, 0(usec)
ld r0, 0(cusleep_time)
mul r0, r0, r1
xor r1, r1, r1
l0:
addi r1, r1, 1
cmp cr0, 1, r0, r1
bne cr0, l0
{$endif cpupowerpc}
end;
procedure init_cusleep;
var
bt: int64;
tv: timeval;
i: longint;
label l0;
begin
fpgettimeofday(@tv, nil);
bt := (tv.tv_sec * 1000000) + tv.tv_usec;
asm
{$ifdef cpu386}
xorl %eax, %eax
xorl %ecx, %ecx
l0:
incl %ecx
cmpl %eax, %ecx
jne l0
{$endif cpu386}
{$ifdef cpux86_64}
xorl %eax, %eax
xorl %ecx, %ecx
l0:
incl %ecx
cmpl %eax, %ecx
jne l0
{$endif cpux86_64}
{$ifdef cpupowerpc}
xor r0, r0, r0
xor r1, r1, r1
l0:
addi r1, r1, 1
cmp cr0, 1, r0, r1
bne cr0, l0
{$endif cpupowerpc}
end;
fpgettimeofday(@tv, nil);
cusleep_time := ($100000000 div (((tv.tv_sec * 1000000) + tv.tv_usec) - bt));
bt := (tv.tv_sec * 1000000) + tv.tv_usec;
for i := 1 to 1000000 do
begin
cusleep(1);
end;
fpgettimeofday(@tv, nil);
cusleep_time := cusleep_time - (((((tv.tv_sec * 1000000) + tv.tv_usec) - bt) - 1000000) div 1000);
end;
end. Amint látjátok, itt az inicializáló, a ciklusmérés után, mindjárt mér is egy másodpercet a timer függvénnyel, aztán a mért eredményből kivonja a vártat és az eredményt osztja ezerrel (lévén ugye itt µszekundumokat mértünk, de nanoszekundumokat számolunk) és az egészet kivonja az eredeti ciklusszámból. Az operandusok előjelesek, azaz, ha épp hosszabbítani kellene a várakozást, akkor negatív számot von ki (azaz összead), tehát mind a két irányba jó.
A végeredmény elég jó, a mért/várt különbség ~0.5%-ról ~0.07%-ra csökkent, azaz valamivel egy ezrelék alá. Tehát most már egy µszekundum alatt kevesebbet csúszik, mint 1 ns. |