home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / sys / mac / programm / 18452 < prev    next >
Encoding:
Internet Message Format  |  1992-11-15  |  13.1 KB

  1. Path: sparky!uunet!ogicse!cs.uoregon.edu!mystix.cs.uoregon.edu!mkelly
  2. From: mkelly@mystix.cs.uoregon.edu (Michael A. Kelly)
  3. Newsgroups: comp.sys.mac.programmer
  4. Subject: Re: Help! making an assembly routine faster
  5. Message-ID: <1992Nov16.014850.28678@cs.uoregon.edu>
  6. Date: 16 Nov 92 01:48:50 GMT
  7. Article-I.D.: cs.1992Nov16.014850.28678
  8. References: <1992Nov14.091905.29520@cs.uoregon.edu> <1992Nov14.200831.20477@nntp.hut.fi>
  9. Sender: news@cs.uoregon.edu (Netnews Owner)
  10. Organization: University of Oregon Computer and Information Sciences Dept.
  11. Lines: 394
  12.  
  13. In article <1992Nov14.200831.20477@nntp.hut.fi> jmunkki@vipunen.hut.fi (Juri Munkki) writes:
  14. >In article <1992Nov14.091905.29520@cs.uoregon.edu> mkelly@mystix.cs.uoregon.edu (Michael A. Kelly) writes:
  15. >>Hey, all you assembly hackers!  How can I make this routine faster?  As it
  16. >>is it's only about 40% faster than CopyMask.  (I'm using Think C 5.)
  17. >
  18. >This sounds like something I might be able  to help with... let's see...
  19. >
  20. >>    src = GetPixBaseAddr( srcMap ) + (long) ((*srcMap)->rowBytes & 0x3FFF) * srcPt.v + srcPt.h;
  21. >
  22. >Shouldn't you cast to long before the multiply? It looks to me like you are
  23. >casting the result of a short multiply, but I could be wrong, since I don't
  24. >want to check this from a C book right now.
  25.  
  26. Yep, but if you look closely at the parens, I think you'll find that that's
  27. what I'm doing.
  28.  
  29. >Another possibility is to grab just a few mask bits (like 4, as I
  30. >suggested) at a time and write special code for all the 16 possible
  31. >cases. Use a jump table to select the code to use.
  32.  
  33. OK, I did that, and managed to almost triple the speed of my original routine,
  34. making the new routine about four times as fast as CopyMask.  And yet, I'd
  35. like to make it even faster.  So suggestions are welcome.
  36.  
  37. Someone else suggested that I just make the mask the same depth as the pixmaps,
  38. so that I could use the mask directly instead of having to extract bits from
  39. it.  This turned out to be slower than the jump table approach, only about
  40. three times as fast as CopyMask.  Of course, the problem could be with my
  41. assembly skills rather than with the theory.
  42.  
  43. So, here are the resulting routines.  The first uses the jump table approach,
  44. the second uses the wide mask approach.  Can they be made even faster??
  45.  
  46.  
  47. /*
  48.  * Quick8CopyMask
  49.  *
  50.  *    The QuickXCopyMask family are much faster versions of CopyMask
  51.  *    that don't do clipping, dithering, etc.  The source and destination
  52.  *    PixMaps are expected to have the same bit depth.  The X in the name
  53.  *    represents the expected bit depth of the source and destination PixMaps.
  54.  *
  55.  *    The mask is expected to be exactly the same size as the rectangle
  56.  *    that is being copied.
  57.  *
  58.  */
  59.  
  60. void Quick8CopyMask(
  61.     PixMapHandle    srcMap,
  62.     PixMapHandle    dstMap,
  63.     Ptr             mask,
  64.     Point           srcPt,
  65.     Point           dstPt,
  66.     short           width,
  67.     short           height )
  68. {
  69.  
  70.     register char   *src;
  71.     register char   *dst;
  72.     register long   srcNewline;
  73.     register long   dstNewline;
  74.     char            mode32 = QD32COMPATIBLE;
  75.     short           w = (width >> 3) - 1;
  76.     short           e = (width & 0x07) - 1;
  77.     short           h = height - 1;
  78.     
  79.     // Set up pointers to the beginning of the memory to copy
  80.     // and calculate the newline value for the source and destination
  81.     
  82.     src = GetPixBaseAddr( srcMap ) + (long) ((*srcMap)->rowBytes & 0x3fff) * srcPt.v + srcPt.h;
  83.     srcNewline = ((*srcMap)->rowBytes & 0x3fff) - width;
  84.     
  85.     dst = GetPixBaseAddr( dstMap ) + (long) ((*dstMap)->rowBytes & 0x3fff) * dstPt.v + dstPt.h;
  86.     dstNewline = ((*dstMap)->rowBytes & 0x3fff) - width;
  87.  
  88.     // Switch into 32 bit addressing mode
  89.     
  90.     SwapMMUMode( &mode32 );
  91.     
  92.     // Copy the rect from the source to the destination
  93.     
  94.     asm {
  95.     
  96.         MOVE.W    h, D0               ; put height loop variable in D0
  97.         MOVEA.L   src, A0             ; put the source pixmap address in A0
  98.         MOVEA.L   dst, A1             ; put the destination address in A1
  99.         MOVEA.L   mask, A2            ; put the mask address in A2
  100.         
  101.     @1:                               ; copy the next row
  102.         MOVE.W    w, D1
  103.         
  104.     @2:                               ; copy the next eight bytes in the row
  105.     
  106.         MOVE.B    (A2), D2            ; copy the next mask byte
  107.         
  108.         TST.B     D2
  109.         BEQ       @nocopy             ; if zero, don't copy anything
  110.         
  111.         CMPI.B    #0xFF, D2
  112.         BNE       @hardway            ; don't copy everything
  113.         
  114.         MOVE.L    (A0)+, (A1)+        ; copy all bytes
  115.         MOVE.L    (A0)+, (A1)+
  116.         ADDQ.L    #1, A2
  117.         JMP       @endloop
  118.     
  119.     @nocopy:                          ; copy no bytes
  120.         ADDQ.L    #8, A0
  121.         ADDQ.L    #8, A1
  122.         ADDQ.L    #1, A2
  123.         JMP       @endloop
  124.     
  125.     @hardway:
  126.         ANDI.L    #0xF0, D2           ; mask off the low four bits
  127.         LSR.W     #4, D2              ; shift bits 4-7 into bits 0-3
  128.         ADD.W     D2, D2              ; double the index
  129.         ADD.W     @table(D2.W), D2    ; calculate the address
  130.         JSR       @table(D2.W)        ; plot four pixels
  131.         
  132.         CLR.L     D2                  ; clear the mask register
  133.         MOVE.B    (A2)+, D2           ; copy the next mask byte
  134.         ANDI.B    #0xF, D2            ; mask off the high four bits
  135.         ADD.W     D2, D2              ; double the index
  136.         ADD.W     @table(D2.W), D2    ; calculate the address
  137.         JSR       @table(D2.W)        ; plot four pixels
  138.     
  139.     @endloop:
  140.         DBF       D1, @2
  141.         
  142.         TST.W     e
  143.         BLT       @4                  ; continue if e is less than 0
  144.     
  145.         MOVE.W    e, D1               ; copy the extra bytes, if any
  146.     
  147.     @3:                               ; copy the next byte
  148.  
  149.         MOVEQ.L   #0, D3              ; initialize the bit counter    
  150.         BTST      D3, (A2)            ; test the next bit in the mask
  151.         BEQ       @skip               ; if zero, continue
  152.         MOVE.B    (A0)+, (A1)+        ; else copy the pixel
  153.         JMP       @incb
  154.     @skip:
  155.         ADDQ.L    #1, A0
  156.         ADDQ.L    #1, A1
  157.     @incb:
  158.         ADDQ.L    #1, D3              ; increment the bit number
  159.         
  160.         DBF       D1, @3
  161.     
  162.     @4:
  163.         ADDA.L    srcNewline, A0      ; bring the src pointer to the start of the next row
  164.         ADDA.L    dstNewline, A1      ; bring the dst pointer to the start of the next row
  165.         
  166.         DBF       D0, @1
  167.         
  168.         JMP       @end                ; skip to the end
  169.         
  170.     @table:
  171.         DC.W      @sub0
  172.         DC.W      @sub1
  173.         DC.W      @sub2
  174.         DC.W      @sub3
  175.         DC.W      @sub4
  176.         DC.W      @sub5
  177.         DC.W      @sub6
  178.         DC.W      @sub7
  179.         DC.W      @sub8
  180.         DC.W      @sub9
  181.         DC.W      @sub10
  182.         DC.W      @sub11
  183.         DC.W      @sub12
  184.         DC.W      @sub13
  185.         DC.W      @sub14
  186.         DC.W      @sub15
  187.     
  188.     @sub0:                            ; mask = 0000, draw nothing
  189.         ADDQ.L    #4, A0
  190.         ADDQ.L    #4, A1
  191.         RTS
  192.     
  193.     @sub1:                            ; mask = 0001
  194.         ADDQ.L    #3, A0
  195.         ADDQ.L    #3, A1
  196.         MOVE.B    (A0)+, (A1)+
  197.         RTS
  198.     
  199.     @sub2:                            ; mask = 0010
  200.         ADDQ.L    #2, A0
  201.         ADDQ.L    #2, A1
  202.         MOVE.B    (A0)+, (A1)+
  203.         ADDQ.L    #1, A0
  204.         ADDQ.L    #1, A1
  205.         RTS
  206.     
  207.     @sub3:                            ; mask = 0011
  208.         ADDQ.L    #2, A0
  209.         ADDQ.L    #2, A1
  210.         MOVE.W    (A0)+, (A1)+
  211.         RTS
  212.     
  213.     @sub4:                            ; mask = 0100
  214.         ADDQ.L    #1, A0
  215.         ADDQ.L    #1, A1
  216.         MOVE.B    (A0)+, (A1)+
  217.         ADDQ.L    #2, A0
  218.         ADDQ.L    #2, A1
  219.         RTS
  220.     
  221.     @sub5:                            ; mask = 0101
  222.         ADDQ.L    #1, A0
  223.         ADDQ.L    #1, A1
  224.         MOVE.B    (A0)+, (A1)+
  225.         ADDQ.L    #1, A0
  226.         ADDQ.L    #1, A1
  227.         MOVE.B    (A0)+, (A1)+
  228.         RTS
  229.     
  230.     @sub6:                            ; mask = 0110
  231.         ADDQ.L    #1, A0
  232.         ADDQ.L    #1, A1
  233.         MOVE.B    (A0)+, (A1)+
  234.         ADDQ.L    #1, A0
  235.         ADDQ.L    #1, A1
  236.         RTS
  237.     
  238.     @sub7:                            ; mask = 0111
  239.         ADDQ.L    #1, A0
  240.         ADDQ.L    #1, A1
  241.         MOVE.B    (A0)+, (A1)+
  242.         MOVE.W    (A0)+, (A1)+
  243.         RTS
  244.     
  245.     @sub8:                            ; mask = 1000
  246.         MOVE.B    (A0)+, (A1)+
  247.         ADDQ.L    #3, A0
  248.         ADDQ.L    #3, A1
  249.         RTS
  250.     
  251.     @sub9:                            ; mask = 1001
  252.         MOVE.B    (A0)+, (A1)+
  253.         ADDQ.L    #2, A0
  254.         ADDQ.L    #2, A1
  255.         MOVE.B    (A0)+, (A1)+
  256.         RTS
  257.     
  258.     @sub10:                            ; mask = 1010
  259.         MOVE.B    (A0)+, (A1)+
  260.         ADDQ.L    #1, A0
  261.         ADDQ.L    #1, A1
  262.         MOVE.B    (A0)+, (A1)+
  263.         ADDQ.L    #1, A0
  264.         ADDQ.L    #1, A1
  265.         RTS
  266.     
  267.     @sub11:                            ; mask = 1011
  268.         MOVE.B    (A0)+, (A1)+
  269.         ADDQ.L    #1, A0
  270.         ADDQ.L    #1, A1
  271.         MOVE.W    (A0)+, (A1)+
  272.         RTS
  273.     
  274.     @sub12:                            ; mask = 1100
  275.         MOVE.W    (A0)+, (A1)+
  276.         ADDQ.L    #2, A0
  277.         ADDQ.L    #2, A1
  278.         RTS
  279.     
  280.     @sub13:                            ; mask = 1101
  281.         MOVE.W    (A0)+, (A1)+
  282.         ADDQ.L    #1, A0
  283.         ADDQ.L    #1, A1
  284.         MOVE.B    (A0)+, (A1)+
  285.         RTS
  286.     
  287.     @sub14:                            ; mask = 1110
  288.         MOVE.W    (A0)+, (A1)+
  289.         MOVE.B    (A0)+, (A1)+
  290.         ADDQ.L    #1, A0
  291.         ADDQ.L    #1, A1
  292.         RTS
  293.     
  294.     @sub15:                            ; mask = 1111
  295.         MOVE.L    (A0)+, (A1)+
  296.         RTS
  297.     
  298.     @end:
  299.     
  300.     }
  301.     
  302.     // Switch back to the previous addressing mode
  303.     
  304.     SwapMMUMode( &mode32 );
  305.  
  306. }
  307.  
  308.  
  309.  
  310. And the wide mask approach:
  311.  
  312.  
  313. void Quick8CopyMask(
  314.     PixMapHandle    srcMap,
  315.     PixMapHandle    dstMap,
  316.     Ptr             mask,
  317.     Point           srcPt,
  318.     Point           dstPt,
  319.     short           width,
  320.     short           height )
  321. {
  322.  
  323.     register char   *src;
  324.     register char   *dst;
  325.     register long   srcNewline;
  326.     register long   dstNewline;
  327.     char            mode32 = QD32COMPATIBLE;
  328.     short           w = (width >> 2) - 1;
  329.     short           e = (width & 0x3) - 1;
  330.     short           h = height - 1;
  331.     
  332.     // Set up pointers to the beginning of the memory to copy
  333.     // and calculate the newline value for the source and destination
  334.     
  335.     src = GetPixBaseAddr( srcMap ) + (long) ((*srcMap)->rowBytes & 0x3fff) * srcPt.v + srcPt.h;
  336.     srcNewline = ((*srcMap)->rowBytes & 0x3fff) - width;
  337.     
  338.     dst = GetPixBaseAddr( dstMap ) + (long) ((*dstMap)->rowBytes & 0x3fff) * dstPt.v + dstPt.h;
  339.     dstNewline = ((*dstMap)->rowBytes & 0x3fff) - width;
  340.  
  341.     // Switch into 32 bit addressing mode
  342.     
  343.     SwapMMUMode( &mode32 );
  344.     
  345.     // Copy the rect from the source to the destination
  346.     
  347.     asm {
  348.     
  349.         MOVE.W    h, D0               ; put height loop variable in D0
  350.         MOVEA.L   src, A0             ; put the source pixmap address in A0
  351.         MOVEA.L   dst, A1             ; put the destination address in A1
  352.         MOVEA.L   mask, A2            ; put the mask address in A2
  353.         
  354.     @1:                               ; copy the next row
  355.         MOVE.W    w, D1
  356.         
  357.     @2:                               ; copy the next four bytes in the row
  358.         
  359.         MOVE.L    (A2)+, D2           ; copy the mask to D2
  360.         MOVE.L    D2, D4              ; save the mask
  361.         NOT.L     D4                  ; invert the mask
  362.         AND.L     (A0)+, D2           ; compute the pixels to be copied
  363.         AND.L     (A1), D4            ; compute the pixels to be saved
  364.         OR.L      D2, D4              ; combine the copied and saved pixels
  365.         MOVE.L    D4, (A1)+           ; copy the pixels
  366.         
  367.         DBF       D1, @2
  368.         
  369.         TST.W     e
  370.         BLT       @4                  ; continue if e is less than 0
  371.     
  372.         MOVE.W    e, D1               ; copy the extra bytes, if any
  373.     
  374.     @3:                               ; copy the next byte
  375.     
  376.         MOVE.B    (A2)+, D2           ; copy the mask to D2
  377.         MOVE.B    D2, D4              ; save the mask
  378.         NOT.B     D4                  ; invert the mask
  379.         AND.B     (A0)+, D2           ; compute the pixels to be copied
  380.         AND.B     (A1), D4            ; compute the pixels to be saved
  381.         OR.B      D2, D4              ; combine the copied and saved pixels
  382.         MOVE.B    D4, (A1)+           ; copy the pixels
  383.         
  384.         DBF       D1, @3
  385.     
  386.     @4:
  387.         ADDA.L    srcNewline, A0      ; bring the src pointer to the start of the next row
  388.         ADDA.L    dstNewline, A1      ; bring the dst pointer to the start of the next row
  389.         
  390.         DBF       D0, @1
  391.     
  392.     }
  393.     
  394.     // Switch back to the previous addressing mode
  395.     
  396.     SwapMMUMode( &mode32 );
  397.  
  398. }
  399.  
  400.  
  401.  
  402. -- 
  403. _____________________________________________________________________________
  404. Michael A. Kelly                                               Senior Partner
  405. mkelly@cs.uoregon.edu                                      High Risk Ventures
  406. _____________________________________________________________________________
  407.