Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Delphi - Důvěryhodnost GetTickCount

Dobrý den,
snažím se optimalizovat program psaný v jazyce Pascal. Jedná se o konzolovou aplikaci. Na počátku zjistím čas systému pomocí GetTickCount a na konci provedu odečet od konečného času získaného opět GetTickCount. Je tato metoda zjišťování délky trvání algoritmů důvěryhoná, je systémový čas lineární?

Důvod otázky:

Program využívá funkce Random(), ale ne funkci Randomize, takže měření by mělo probíhat se stejnou tabulkou náhodných čísel. Používal jsem 4 lokální proměnné Boolean. Po nějaké době jsem je přestal používat v programu, ale nechal jsem je nadeklarované. Prováděl jsem měření pomocí výše uvedené metody.

Měření s nevyužívanými proměnnými: 4875, 4859 (Tyto dvě hodnoty se střídají)
Měření bez nevyužitých proměnných: 4968, 5000, 5109, 4969, 4984, atd. (Téměř každé měření jinou hodnotu)

Děkuji

Předmět Autor Datum
Je to doveryhodne ak nejaky driver nezakaze IRQs na viac jak 1ms apod. Granularita toho gettickcount…
MM.. 26.10.2012 14:18
MM..
Já se nedivím, že se pořád mění, já se divím, že v prvním případě se právě nemění. BTW: IRQ je látk…
Telever 26.10.2012 14:22
Telever
ona sa meni o tych 10ms (jeden tick timera), 150ms vykyvy su uz fakt vela, bud to je na inom HW ktor…
MM.. 26.10.2012 14:24
MM..
inac bolo by dobre keby uvadzal cely kod, ptz vykyvy 150ms uz normalne nie su, takze ma nejaku haluz…
MM.. 26.10.2012 14:23
MM..
Nejedná se o kód programu, ale výsledky jsou stejné. program Project1; {$APPTYPE CONSOLE} uses Sys…
Telever 26.10.2012 14:27
Telever
a v nudzaku? A skompiluj to preistotu ako release, ne debug. (p.s. take vykyvy nie su normalne)
MM.. 26.10.2012 14:31
MM..
Zkompilovano jako Release, restartováno do Nouzového režimu, provedeno 15 měření: 4968, 5032, 4891,…
Telever 26.10.2012 14:51
Telever
Ono vypadky na tych 7000 raz za cas (nie furt) su normalne ptz Win urobi taskswitch lebo potrebuje o…
MM.. 26.10.2012 14:58
MM..
Overit si to mozes aj pomocou TSC, Time_Stamp_Counter, hladaj googlom nejake read TSC Delphi apod. T…
MM.. 26.10.2012 14:35
MM..
no IMHO vzdy nameras rozny cas, lebo pocas behu tvojho programu ti moze vytazovat procesor aj nieco…
nl12345 26.10.2012 14:54
nl12345
Počítal jsem s tím, že to bude pokaždé jiné, ale pořád jsem nezjistil, proč na to má vliv zadeklarov…
Telever 26.10.2012 14:58
Telever
Nema to na to vplyv (prvykrat to bolo urcite testovane za inych podmienok)
MM.. 26.10.2012 14:59
MM..
Znamená to tedy, že nelze program optimalizovat pouhým zjišťováním délky jeho trvání?
Telever 26.10.2012 15:02
Telever
Lze ale musis to pred a po optimalizacii merat na jednom HW a za stejnych podmienok (nie ze ti tam p…
MM.. 26.10.2012 15:05
MM..
ide to uvedom si, ale, ze istu optimalizaciu za teba uz robi prekladac, takze kludne sa ti moze stat…
nl12345 26.10.2012 15:09
nl12345
Alebo z ineho pohladu. Vykyv 100ms u 5000ms trvania je 2%, u optimalizacie sa bavime o desiatkach pe…
MM.. 26.10.2012 15:23
MM..
Děkuji za pomoc, zkusil jsem to s odpojenými USB a hodnoty byly sobě blíže. Měření provádím jen s ma…
Telever 26.10.2012 16:31
Telever
2% je stejne nezmysel, napis to v assembleri s podporou SSE a pojde to mozno aj 4x rychlejsie.
MM.. 26.10.2012 16:34
MM..
O tom moc dobře vím, každopádně děkuji za radu.
Telever 26.10.2012 17:05
Telever
v paralelnych vypoctoch je tvoja sila :)
nl12345 26.10.2012 16:49
nl12345
Hurá na Umíme to s Delphi, 51. díl – vlákna a paralelní programování :))
Telever 26.10.2012 17:08
Telever
Máš to nějaké pomalé...:-D Java 1.6.0, stará E6300. public class Test { public static void main(Str…
MaSo 26.10.2012 17:55
MaSo
Furt to mas pomale. public class Test { public static void main(String[] args) { long timeBefore =…
MM.. 26.10.2012 18:12
MM..
0 ms mas proto, ze ty tam pro zmenu nemas ten cyklus ;-)
Jan Fiala 26.10.2012 19:51
Jan Fiala
No jasně tak tomuhle kodu neverim ani kozu. Například Oracle level optimalizeru +2 by te s tim neka…
AZOR 26.10.2012 18:19
AZOR
Vsak jasně, kdybych tam dal VM argument -server (možná by stačila i tiered compilation), pravděpodob…
MaSo 26.10.2012 18:28
MaSo
Inac nie som si isty ci do long v jave ulozis 10^9 (neviem zhlavy nechce sa mi to hladat), takze si…
MM.. 26.10.2012 18:38
MM..
Uložíš, nerobil...:-)
MaSo 26.10.2012 18:40
MaSo
Máš to nějaké pomalé... Java 1.6.0, stará E6300. Pomale to ma proto, ze decrementuje primo ten exte…
Jan Fiala 26.10.2012 19:49
Jan Fiala
A kdyz I nadeklaruju jako LongInt misto Int64 (protoze to uz je hodne velky kalibr), tak jsem s case…
Jan Fiala 26.10.2012 19:58
Jan Fiala
Jaký máš HW? V Javě vlastně stačí normal int. Teď jsem na 850ms, níž už to na mojem HW asi nesrazím…
MaSo 26.10.2012 20:01
MaSo
Hardware? Lenovo ThinkPad T61 ;-) Stejné výsledky jsem na tom notebooku dostal i ve VirtualBoxu. Po…
Jan Fiala 27.10.2012 11:13
Jan Fiala
358 na i5-2410M poslední
Wikan 27.10.2012 12:14
Wikan

Je to doveryhodne ak nejaky driver nezakaze IRQs na viac jak 1ms apod. Granularita toho gettickcount je tusim okolo //edit:10ms.
Ked chces presnejsie tak treba ist na HW a citat z I/O space ACPI timer, na to ale treba privilegia (alebo I/O driver)

BTW. chalan asi moc o PC nevie ked sa cuduje ze je furt hodnota ina. Pocul uz o IRQ?

Nejedná se o kód programu, ale výsledky jsou stejné.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows, Math;

var
  prvniCas, druhyCas: Cardinal;
  i: Extended;
begin
  prvniCas := GetTickCount;
  i := Power(10, 9);
  while (i>0) do
    begin
      i := i-1;
    end;
  druhyCas := GetTickCount;
  writeln(inttostr(druhyCas-prvniCas)); 
end.

Moje výsledky: 4891, 5381...

Ono vypadky na tych 7000 raz za cas (nie furt) su normalne ptz Win urobi taskswitch lebo potrebuje obcas nieco riesit v kerneli (alebo USB zariadenia potrebuju obsluhovat furt apod), skus to na dualcore CPU tam to musi byt stabilne. P.S. alebo skus odpojit vsetko od USB, a trebars aj LAN. A vypni antivir.

Lze ale musis to pred a po optimalizacii merat na jednom HW a za stejnych podmienok (nie ze ti tam potom zrazu napr. bezi na pozadi indexovanie a druhykrat ne). A tie hodnoty treba aj priemerovat, trebars vzdy 100merani.
Ja neviem co to mas za HW ale zda sa mi ze ti tam na pozadi bezi nejaky nezmysel ptz take vykyvy som tusim este nevidel.

P.S. idealne to merat na uplne cistom Win, s odpojenou LAN a vsetkymi USB zariadeniami (spusti program a vytiahni trebars aj USB mys a klavesnicu ked to furt skace)

Alebo z ineho pohladu. Vykyv 100ms u 5000ms trvania je 2%, u optimalizacie sa bavime o desiatkach percent, inac by som to nenazyval optimalizaciou ale len zbytocnou robotou. 2% mozes zanedbat. Az to zoptimalizujes ze to bude mat hodnoty okolo 3000 namiesto 5000, tak TO bude optimalizacia ;))

Máš to nějaké pomalé...:-D Java 1.6.0, stará E6300.

public class Test {

    public static void main(String[] args) {
            long timeBefore = System.nanoTime();
            double i = Math.pow(10, 9);
            long retyped = (long) i;

            while (retyped > 0) {
                retyped = retyped - 1;
            }

            long timeAfter = System.nanoTime();
            long time = (timeAfter - timeBefore) / 1000000;
            System.out.println(time + " ms");
        }
}
2536 ms
2534 ms
2532 ms
2543 ms
2537 ms
2535 ms....atd.

Furt to mas pomale.

public class Test {

    public static void main(String[] args) {
            long timeBefore = System.nanoTime();

            double i = Math.pow(10, 9);
            long retyped = 0;

            long timeAfter = System.nanoTime();
            long time = (timeAfter - timeBefore) / 1000000;
            System.out.println(time + " ms");
        }
}

0 ms :)

Zaujimave je to len s realnym kodom ktory fakt nieco zlozite rata.

No jasně tak tomuhle kodu neverim ani kozu.

Například Oracle level optimalizeru +2 by te s tim nekam poslal - while by nespoustel, protoze proc by to kurva taky delal, kdyz to pak nikde nepouzivas, tim chci rict ze zatimco vy si tu hrajete buhvinaco, tak kompilator s tim dela buhvico. Ja napriklad vim, ze v Oracle se ti na to while za urcitych okolosti vysere :-D a to pak to tu muzete asi tezko srovávat.

Máš to nějaké pomalé... Java 1.6.0, stará E6300.

Pomale to ma proto, ze decrementuje primo ten extended. Pokud to, stejne jako ty, pretypuje na LongInt (v Delphi na Int64), pak to trva stejne jako u tebe ;-)

var
  prvniCas, druhyCas: Cardinal;
  i: Int64;
begin
  prvniCas := GetTickCount;
  i := Trunc(Power(10, 9));
  repeat
      Dec(i);
  until i=0;
  druhyCas := GetTickCount;
  writeln(inttostr(druhyCas-prvniCas));
  Readln;
end.

Zkousel jsem, jestli se nejak projevi Do While a Repeat - Until a ne :-)

Zpět do poradny Odpovědět na původní otázku Nahoru