[Back to MEMORY SWAG index] [Back to Main SWAG index] [Original]

    program move32_test;

    USES Crt;

    const count=1000;
    var block1,block2:pointer;
        i,time:longint;
        timer:longint absolute $40:$6C;
        size:word;

    procedure Move32(var source,dest;count:word);assembler;

    asm
                    PUSH    DS
                    LDS     SI,source
                    LES     DI,dest
                    MOV     CX,count
                    SHR     CX,1
                    JNC     @@1
                    MOVSB
    @@1:            SHR     CX,1
                    JNC     @@2
                    MOVSW
    @@2:            DB      66h
                    REP     MOVSW
                    POP     DS
    end;

    { --- Mainprog --- }
    begin

      clrScr;
      getmem(block1,65010);
      getmem(block2,65010);

      for size:=65000 to 65003 do
        begin

         writeln('Timing blocks of ',size,' bytes :');

         writeln('  Timing Move ...');
         time:=timer;
         for i:=1 to count do
           move(block1^,block2^,size);
         writeln('  Time for ',count,' Move''s   : ',(timer-time)/18.2:8:1,' s');

         writeln('  Timing Move32 ...');
         time:=timer;
         for i:=1 to count do
           move32(block1^,block2^,size);
         writeln('  Time for ',count,' Move32''s : ',(timer-time)/18.2:8:1,' s');

        end;

    end.
    { -------------------------------------------------------- }

    If you can't find anything wrong in it, test it !
    Here are the results on a 486DX4-100 :

    Timing blocks of 65000 bytes :
      Timing Move ...
      Time for 1000 Move's   :     11.0 s
      Timing Move32 ...
      Time for 1000 Move32's :      3.6 s
    Timing blocks of 65001 bytes :
      Timing Move ...
      Time for 1000 Move's   :     11.0 s
      Timing Move32 ...
      Time for 1000 Move32's :      6.0 s
    Timing blocks of 65002 bytes :
      Timing Move ...
      Time for 1000 Move's   :     11.0 s
      Timing Move32 ...
      Time for 1000 Move32's :      6.0 s
    Timing blocks of 65003 bytes :
      Timing Move ...
      Time for 1000 Move's   :     11.0 s
      Timing Move32 ...
      Time for 1000 Move32's :      6.0 s

    3 times faster on a 4 byte boundary and still almost twice as fast on other
    addresses ! I think that's a nice score...
     EH> For REP MOVSD to work faster the values to be moved have to be on "32
    bit" EH> addresses, that is: both SI and DI have to be a multiple of 4.
     EH> You didn't test for that and with the extra MOVSB and MOVSW it might well
     EH> be they are on a multiple of 4 + 1 or 3 (as the aligment of TP normally
    is EH> on EVEN addresses).

    You're right about that, maybe I'll work on it... some day. ;-)

     EH> Apart from that you didn't test for overlap (does the move partially
     EH> overwrite the bytes TO be moved, because then those bytes have to be
    moved EH> first)

    I hadn't tought about that. I'm not often moving overlapping blocks though.
    Are you sure the TP Move checks for that ? (I mean, do you not only assume,
    but have you tested it ? :-))
     EH> and you didn't set a direction flag so it just MIGHT be you're
     EH> moving the wrong bytes (mostly the direction flag IS upwards, but it just
     EH> might be downwards, which means you're moving the bytes BELOW "ds:si" to
     EH> "es:di").

    The direction flag is assumed to be cleared in TP. Every procudere that
    changes it, should clear it again. But it's not forbidden to do a CLD of
    course...
     EH> A complete Move32 has to be much more complicated than this (and much
     EH> bigger, thus). Further Move is most often used to/from screen memory and
     EH> unless you got a PCI screen card 32-bits moves are not possible to screen
     EH> memory (the cpu will automatically do each 32-bit doubleword as 2 16-bits
     EH> words, as the bus is only 16 bits).

    PCI (and VLB) are becoming more common today, so I don't see the problem...
    I tested this with mapping the 2'nd block to $A000 in mode 13h. And I've found
    these _strange_ results with a VLB card :
    Timing blocks of 65000 bytes :
      Timing Move ...
      Time for 1000 Move's   :     10.7 s
      Timing Move32 ...
      Time for 1000 Move32's :      3.4 s
    Timing blocks of 65001 bytes :
      Timing Move ...
      Time for 1000 Move's   :     10.7 s
      Timing Move32 ...
      Time for 1000 Move32's :      5.8 s
    Timing blocks of 65002 bytes :
      Timing Move ...
      Time for 1000 Move's   :     10.6 s
      Timing Move32 ...
      Time for 1000 Move32's :      5.8 s
    Timing blocks of 65003 bytes :
      Timing Move ...
      Time for 1000 Move's   :     10.6 s
      Timing Move32 ...
      Time for 1000 Move32's :      5.8 s

    I always tought videoRAM was SLOWER than normal RAM ???
    Do you have an explanation for this ?

[Back to MEMORY SWAG index] [Back to Main SWAG index] [Original]