(* ------------------------------------------------------------------------
  :Program.     SpeedTest.
  :Contents.    Proceduren zum Zeittest von 'Copy' u.a. aus Speed.
  :Author.      Klaus Hlawaty.
  :Address.     Waldhof
  :Address.     3579 Schrecksbach
  :History.     v1.0 - 18.12.90.
  :Imports.     Speed.
  :Imports.     KHTime.
  :Copyright.   PD
  :Language.    Oberon v2.13
  :Translator.  OBERON v2.13 / OLink v2.13d
------------------------------------------------------------------------ *)
MODULE SpeedTest;

IMPORT
         Beep,
         BreakRq,
         io,
         KHTime,
         Mouse,
         NoGuruRq,
      rc:RealConversions,
      Rq:Requests,
         Speed,            (* Wird getestet *)
       s:SYSTEM;

CONST ArrM* = 40000;       (* Array größer als 32767 *)
      TLoop = 100;         (* Bei TLoop = 1000, Wartezeit > 5 min *)

TYPE
      StrT*  = ARRAY ArrM OF CHAR;
VAR
      x1*,
      x2* : StrT;
      z1*,
      z2* : INTEGER;

      t1, t2 : KHTime.TTime;
      r      : REAL;
      Str    : ARRAY 30 OF CHAR;

      Trenn  : ARRAY 80 OF CHAR;

BEGIN
   BreakRq.CtrlCOn;
   io.WriteString("Das Program benutzt zwei Array's 'x1' und 'x2' mit einer\n");
   io.WriteString("Länge von jeweils 40000 Bytes\n");
   io.WriteString("Alle Schleifen werden TLoop =");
   io.WriteInt   (TLoop,6);
   io.WriteString("mal wiederholt\n");
   Speed.FillC("=",70,Trenn); Trenn[70] := "\n";
   io.WriteString(Trenn);
   io.WriteString("Hier erfolgt eine Zuweistung x2 := x1:\n");
   io.WriteString("Normal:");
   KHTime.GetTime(t1);
   z1 := 0;
   REPEAT
      (* $NilChk- $OvflChk- $RangeChk- *)
      x2 := x1;
      (* $NilChk= $OvflChk= $RangeChk= *)
      INC(z1);
   UNTIL z1 >= TLoop;
   KHTime.GetTime(t2);
   Beep.Beep(TRUE);
   r := (t2.ATicks-t1.ATicks)/50;
   Rq.Assert(rc.RealToString(r,Str,5,3,FALSE),"RealConv: Fehler");
   io.WriteString(Str);
   io.WriteString(" sec's\n");
   io.WriteString("Speed :");
   KHTime.GetTime(t1);
   z1 := 0;
   REPEAT
      Speed.Copy(x1[0],x2[0],ArrM);
      (* Durch Angabe des 1.Index erfolgt ein Zugriff auf         *)
      (* ein Array größer 32767 !!                                *)
      (* -------------------------------------------------------- *)
      INC(z1);
   UNTIL z1 >= TLoop;
   KHTime.GetTime(t2);
   r := (t2.ATicks-t1.ATicks)/50;
   Rq.Assert(rc.RealToString(r,Str,5,3,FALSE),"RealConv: Fehler");
   io.WriteString(Str);
   io.WriteString(" sec's\n");
   Beep.Beep(TRUE);
   Speed.FillC("-",70,Trenn); Trenn[70] := "\n";
   io.WriteString(Trenn);
   io.WriteString("Hier werden 10000 Bytes von x1 nach x2 kopiert\n");
   io.WriteString("1.) Normal : x2[z2] := x1[z1]\n");
   io.WriteString("2.) Chk-   : wie oben mit $NilChk- $OvflChk- $RangeChk-\n");
   io.WriteString("3.) Speed  : Kopiert x1[5000] nach x2[15000] volle Geschwindigkeit\n");
   io.WriteString("4.) Speed  : Kopiert x1[1](ungerade) nach x2[2](gerade) Byteweise\n");
   io.WriteString("1.) Normal (10000Byte):");
   KHTime.GetTime(t1);
   z1 := 0;
   REPEAT
      z2 := 1;
      REPEAT
         x2[z2] := x1[z2];
         INC(z2);
      UNTIL(z2 > 10001);
      INC(z1);
   UNTIL z1 >= TLoop;
   KHTime.GetTime(t2);
   Beep.Beep(TRUE);
   r := (t2.ATicks-t1.ATicks)/50;
   Rq.Assert(rc.RealToString(r,Str,5,3,FALSE),"RealConv: Fehler");
   io.WriteString(Str);
   io.WriteString(" sec's\n");
   io.WriteString("2.) Chk-   (10000Byte):");
   (* Hier erfolgt der Zugriff mit abgeschalteten Überprüfungen *)
   KHTime.GetTime(t1);
   z1 := 0;
   (* $NilChk- $OvflChk- $RangeChk- *)
   REPEAT
      z2 := 10000;
      REPEAT
         x2[z2] := x1[z2];
         INC(z2);
      UNTIL(z2 > 20001);
      INC(z1);
   UNTIL z1 >= TLoop;
   (* $NilChk= $OvflChk= $RangeChk= *)
   KHTime.GetTime(t2);
   Beep.Beep(TRUE);
   r := (t2.ATicks-t1.ATicks)/50;
   Rq.Assert(rc.RealToString(r,Str,5,3,FALSE),"RealConv: Fehler");
   io.WriteString(Str);
   io.WriteString(" sec's\n");
   io.WriteString("3.) Speed  (10000/48 ):");
   KHTime.GetTime(t1);
   z1 := 0;
   REPEAT
      Speed.Copy(x1[5000],x2[15000],10000);
      (* -------------------------------------------------------- *)
      (* Copiert von x1Ptr Index 5000 auf x2Ptr Index 15000       *)
      (* insgesamt 10000 Bytes !!                                 *)
      (* Dieser Transfer ist komplexer als die obigen Beispiele   *)
      (* Andererseits werden oben Bytes copiert, während in       *)
      (* Speed.Copy gleichzeitig bis zu 48 Bytes in zwei Befehlen *)
      (* bewegt werden.                                           *)
      (* -------------------------------------------------------- *)
      INC(z1);
   UNTIL z1 >= TLoop;
   KHTime.GetTime(t2);
   r := (t2.ATicks-t1.ATicks)/50;
   Rq.Assert(rc.RealToString(r,Str,5,3,FALSE),"RealConv: Fehler");
   io.WriteString(Str);
   io.WriteString(" sec's");
   io.WriteLn;
   io.WriteString("4.) Speed  (10000Byte):");
   KHTime.GetTime(t1);
   z1 := 0;
   REPEAT
      Speed.Copy(x1[1],x2[2],10000);
      (* -------------------------------------------------------- *)
      (* Copiert von x1Ptr Index 1 auf x2Ptr Index 2              *)
      (* insgesamt 10000 Bytes hierbei wird durch die Verwendung  *)
      (* einer geraden (1) und einer ungeraden (2) Addresse eine  *)
      (* byteweises Kopieren erzwungen.                           *)
      (* Da die Indexzählung mit 0 beginnt ist Index 1 gerade und *)
      (* Index 2 ungerade !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  *)
      (* -------------------------------------------------------- *)
      INC(z1);
   UNTIL z1 >= TLoop;
   KHTime.GetTime(t2);
   r := (t2.ATicks-t1.ATicks)/50;
   Rq.Assert(rc.RealToString(r,Str,5,3,FALSE),"RealConv: Fehler");
   io.WriteString(Str);
   io.WriteString(" sec's");
   io.WriteLn;
   Beep.Beep(TRUE);

CLOSE
   Beep.Beep(FALSE);
   Beep.Beep(TRUE);
   Beep.Beep(FALSE);
   Speed.FillC("=",70,Trenn); Trenn[70] := "\n";
   io.WriteString(Trenn);
   io.WriteString("\n Rechte Mausetaste !!!!!!!!! \n");
   REPEAT UNTIL Mouse.rightButton;
END SpeedTest.
