TCH (statz) | #1, Főfasz (10443) |
2757 | #2994 | ^ | Idézet | Fri, 27 Dec 2013 02:40:16 +01 |
31.46.*.* | *.catv.pool.telekom.hu |
Minthogy minden épeszű módszer kudarcot vallott, így kénytelen voltam egy olyan módszerhez folyamodni, ami manapság nem igazán nevezhető épeszűnek. Most mondjam, hogy persze, hogy ez vált be? A lényeg, hogy a rendszerórából lekérem az időt, utána lefuttatok egy 4 giga méretű üres ciklust, majd megint lekérem az időt és utána a 4 gigát elosztva az eltelt idővel, megkapom, hogy hány iteráció jut egy µsec-re. Utána ezt felszorzom annyival, amennyi µszekundumot várni akarok és annyiszor pörgetem körbe az üres ciklust. Az eredmény egyelőre kielégítő, mindössze 4-5 ezrelékes eltérés van a várt és a mért eredmény között, tehát elméletileg jelen pillanatban, ha 1 µs-t várakoztatok, akkor az valójában 1.005 µsec-ig fog tartani. Nem elég jó, de mindenképpen haladás a többi totál használhatatlan szeméthez képest. Ha sikerül egy ezrelék - azaz egy nanoszekundum - alá nyomni a különbséget, akkor az már oké lesz. Megosztom a kódot az utókorral, hátha más többre jut. unit cusleep_lib; interface procedure init_cusleep; procedure cusleep(usec: longint); implementation uses unix; var cusleep_time: longint; procedure init_cusleep; var bt: int64; tv: timeval; 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); end; 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; end.És a tesztprogram. program test; uses cusleep_lib, unix; var i: longint; bt: int64; tv: timeval; begin init_cusleep; fpgettimeofday(@tv, nil); bt := (tv.tv_sec * 1000000) + tv.tv_usec; for i := 1 to 10000000 do begin cusleep(1); end; fpgettimeofday(@tv, nil); write(((tv.tv_sec * 1000000) + tv.tv_usec) - bt, #10); end. |