Results 1 to 4 of 4

Thread: 500% snelheids winst op delingen

  1. #1
    Nog 3 maanden student :)
    Join Date
    Oct 2003
    Location
    Sittard
    Posts
    491

    500% snelheids winst op delingen

    Omdat ik laatst bezig was met een programma dat veel delingen moest doen..
    kwam ik erachter dat het nogal veel snelheid slurpte.. toen hoorde ik van een oude docent dat vroeger snelheids winst was te halen door ipv y:= x/100; y:= x*(1/100) te doen. dus heb ik dat eens getest, en inderdaad, dat scheelt een berg aan snelheid..

    ligt aan de cpu natuurlijk, maar meestal kom ik toch wel factor 5 verschil tegen.

    heb maar meteen ff een klein projectje gemaakt met voorbeeld.

    Code:
    Simple Number division:
    Calculating
    First Pass Result:  2147483,64
    Second Pass Result: 2147483,64
    Done, Results:
    / 100  Time:  11,9195 seconds
    / 100  Clock: 42666537 ticks
    * 0.01 Time:  2,3904 seconds
    * 0.01 Clock: 8556545 ticks
    
    Odd Number division:
    First Pass Result:    386238,064748
    Second Pass Result:   386238,064748
    Done, Results:
    / 556     Time:  11,6495 seconds
    / 556     Clock: 41699892 ticks
    * (1/556) Time:  2,4255 seconds
    * (1/556) Clock: 8682027 ticks
      (1/556) = 0,00179856115108 (approximate)
    source:
    Code:
    program DivVsMult;
    
    {$APPTYPE CONSOLE}
    
    uses
      SysUtils,
      Windows;
    
    var
      Start,Stop, Start2, Stop2, Freq:int64;
      i : integer;
      t : real;
      CpuSpeed : integer;
    begin
      { TODO -oUser -cConsole Main : Insert code here }
      { Cpu Speed fastes cpu = 1 slower => 10
        it's just to determin the number of time to do the loop
        Maxint div CpuSpeed is calculated }   
      if ParamCount = 1 then
        CpuSpeed := StrToIntDef(ParamStr(1),1)
      else
        CpuSpeed := 10;
    
      Writeln('Simple Number division:');
      WriteLn('Calculating');
      QueryPerformanceFrequency(freq);
      QueryPerformanceCounter(Start);
      for i:=0 to MaxInt div CpuSpeed do
        t := i / 100;
      QueryPerformanceCounter(Stop);
      WriteLn(Format('First Pass Result:  %f',[t]));
       {  This is needed because the compiler would optimize,
          and would notice the result of the loop isn't used at all,
          so therefor the result is useless.. so depending on the compiler, it will
          choose what to do with it, this disables that optimization
       }
      QueryPerformanceCounter(Start2);
      for i:=0 to MaxInt div CpuSpeed do
        t := i * (1/100);
      QueryPerformanceCounter(Stop2);
      WriteLn(Format('Second Pass Result: %15.6f',[t]));
       {  This is needed because the compiler would optimize,
          and would notice the result of the loop isn't used at all,
          so therefor the result is useless.. so depending on the compiler, it will
          choose what to do with it, this disables that optimization
       }
      WriteLn('Done, Results:');
      Writeln(Format('/ 100  Time:  %6.4f seconds'+#13#10+
                     '/ 100  Clock: %d ticks'+#13#10+
                     '* 0.01 Time:  %6.4f seconds'+#13#10+
                     '* 0.01 Clock: %d ticks',[(Stop-Start) / freq, (Stop-Start), (Stop2-Start2) / freq, (Stop2-Start2)]));
      Writeln;
      Writeln('Odd Number division:');
      QueryPerformanceCounter(Start);
      for i:=0 to high(i) div CpuSpeed do
        t := i / 556;
      QueryPerformanceCounter(Stop);
      WriteLn(Format('First Pass Result:  %15.6f',[t]));
       {  This is needed because the compiler would optimize,
          and would notice the result of the loop isn't used at all,
          so therefor the result is useless.. so depending on the compiler, it will
          choose what to do with it, this disables that optimization
       }
      QueryPerformanceCounter(Start2);
      for i:=0 to high(i) div CpuSpeed do
        t := i * (1/556);
      QueryPerformanceCounter(Stop2);
      WriteLn(Format('Second Pass Result: %15.6f',[t]));
       {  This is needed because the compiler would optimize,
          and would notice the result of the loop isn't used at all,
          so therefor the result is useless.. so depending on the compiler, it will
          choose what to do with it, this disables that optimization
       }
      WriteLn('Done, Results:');
      WriteLn(Format('/ 556     Time:  %6.4f seconds'+#13#10+
                     '/ 556     Clock: %d ticks'+#13#10+
                     '* (1/556) Time:  %6.4f seconds'+#13#10+
                     '* (1/556) Clock: %d ticks',[(Stop-Start) / freq, (Stop-Start), (Stop2-Start2) / freq, (Stop2-Start2)]));
      Writeln(Format('  (1/556) = %15.14f (approximate)',[1/556]));
    //  readln;
    
    end.
    Last edited by Davy Landman; 03-Mar-05 at 14:24.

  2. #2
    Nog 3 maanden student :)
    Join Date
    Oct 2003
    Location
    Sittard
    Posts
    491
    ik was eigenlijk wel benieuwd of er nog andere goede ideëen zijn in de zelfde categorie.

    ik heb ook al eens gekeken naar wat sneller is
    x div 4 of x shr 2 ... maar dat is maar zo'n klein beetje sneller op een heel hoog aantal herhalingen dat het niet waard is..

  3. #3
    De resultaten zijn niet altijd precies hetzelfde. Compile-time vermenigvuldiging en deling zouden met een andere precisie kunnen gebeuren dan run-time. Voor integer operaties gebeurt dat waarschijnlijk niet, maar floating point?

  4. #4
    Nog 3 maanden student :)
    Join Date
    Oct 2003
    Location
    Sittard
    Posts
    491
    nou als ik het goed heb, dan doet de compiler van die * (1/556) een constante maken in het programma. dus niet elke loop weer opnieuw 1/556 uitrekenen.

    heb even gekeken of idd de percisie achteruit gaat bij een vermenigvuldiging.. want dat is inderdaad al een benadering van het echte getal.
    Code:
    Simple Number division:
    Calculating
    First Pass Result:  2147483,64
    Second Pass Result: 2147483,64
    Done, Results:
    / 100  Time:  10,3319 seconds
    / 100  Clock: 36983482 ticks
    * 0.01 Time:  2,0378 seconds
    * 0.01 Clock: 7294251 ticks
    
    Odd Number division:
    First Pass Result:    386238,0647482014610000
    Second Pass Result:   386238,0647482014610000
    Done, Results:
    / 556     Time:  10,0735 seconds
    / 556     Clock: 36058581 ticks
    * (1/556) Time:  2,0446 seconds
    * (1/556) Clock: 7318775 ticks
      (1/556) = 0,0017985611510791 (approximate)
    dus op het 16 digits percisie niveau van een real(double) is het gewoon het zelfde..

    ps. en volgens mij heb ik nu al 4 keer percisie fout geschreve :d

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •