code optimization help

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
animo3d
Posts: 24
Joined: Sun Sep 18, 2011 6:02 am
Location: Monterrey Mexico

code optimization help

Post by animo3d » Tue Jun 09, 2015 4:16 am

Hi, I have been working with chinese led panels succesfully for some time, but for a new application I need to transpose the bits on the led matrix of height of 16 pixels by width of 32 pixels, the bytes are arranged in the matix horizontally and my master is set to send the data in vertical words...

I already have a routine that works nice, I just need a little help from the code gurus to optimize the math a little bit...

this is the working routine:

Code: Select all


Sub ChangeMem()
 For C=0 To 3  'four bytes wide on the module
  For B=0 To 7 'each bit on the horizontal byte 
   For A=0 To 15 'each bit on the vertical word
    BUF(Transp(A)+4*C).bits(7-B)=BufV(B+8*C).bits(A)
   Next
  Next
 Next 
End Sub

where BUF = array of 64 bytes (this is the array I use for the screen refresh)
BufV = array of 32 words (this is the array I get from the Message composer board)
Transp = table of constants of 16 bytes (with the leftmost bytes of the screen on each line: 00, 04, 08, etc)

looks like this operations takes a lot of time and I see some flicker when used continuosly...

any help apreciated...

SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Re: code optimization help

Post by SHughes_Fusion » Tue Jun 09, 2015 7:36 am

Can I make a suggestion that might help? It isn't always obvious or easily replicated how Swordfish compiles this sort of code so if you can find the appropriate routine in the .asm file and post that it will help us see what is going on and suggest ways to optimise.

SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Re: code optimization help

Post by SHughes_Fusion » Tue Jun 09, 2015 9:46 am

A good tip for speeding these sort of things up is to try and avoid referencing arrays when you can use locals and to simplify any repeated calculations if you can. As an example, I had a similar routine for displaying a normal x-oriented bitmap on an LCD screen which works in strips where each byte you write represents a vertical row of 8 pixels. The routine I originally wrote was:

Code: Select all

Public Sub WriteXBitmap(ByRefConst bmap() As Byte, xPos As Byte = 0, yPos As Byte = 0)
  Dim i, j, k, l As Byte
  Dim w As Word
  Dim bm(8) As Byte
  Dim ts As Byte
  Dim ImgWidth, ImgHeight As Byte
  
  Clear(bm)
  
  ImgWidth = bmap(0)/8                  // Width in bytes
  ImgHeight = bmap(1)/8                 // Height in pages
  
  For i = 0 To ImgHeight-1
    Set_Start_Page(i+(yPos / 8))
    Set_Start_Column(D_OFFSET + xPos)

    Start_Data

    For j = 0 To ImgWidth-1              // Bitmap is 16 bytes wide
      w = (i * bmap(0)) + j + 2          // Calculate the offset in the bitmap data table
      For k = 0 To 7
        ts = bmap(w+(k*ImgWidth))
        For l = 0 To 7
          bm(l) = bm(l) >> 1
          bm(l).7 = ts.7
          ts = ts << 1  
        Next
      Next
      
      For k = 0 To 7
        Display_Data(bm(k))
      Next
    Next 
    Stop_Data
  Next 
End Sub
In the context of a program which uses this routine it compiled to 11405 words. I spent a while editing it down and removing array references and calculations where possible. I ended up with:

Code: Select all

Public Sub WriteXBitmap(ByRefConst bmap() As Byte, xPos As Byte = 0, yPos As Byte = 0)
  Dim i, j, k, l As Byte
  Dim w As Word
  Dim bm(8) As Byte
  Dim ts As Byte
  Dim ImgWidth, ImgHeight As Byte
  Dim tb As Byte
  Dim PWidth As Byte
  
  Clear(bm)
  
  PWidth = bmap(0)
  ImgWidth = PWidth/8                   // Width in bytes
  ImgHeight = bmap(1)/8                 // Height in pages
  yPos = yPos / 8
  
  For i = 0 To ImgHeight-1
    Set_Start_Page(yPos)
    Inc(yPos)
    Set_Start_Column(D_OFFSET + xPos)

    Start_Data
    w = (i * PWidth) + 2
    j = ImgWidth
    Repeat
      k = 8
      Repeat
        ts = bmap(w)        
        w = w + ImgWidth
        
        For l = 0 To 7
          tb = bm(l)
          tb = tb >> 1
          tb.7 = ts.7
          bm(l) = tb
          ts = ts << 1  
        Next
        Dec(k)
      Until k = 0
      
      For k = 0 To 7
        Display_Data(bm(k))
      Next
      Inc(w)
      Dec(j)
    Until j = 0
    Stop_Data
  Next 
End Sub
This compiles to 11275 words so I've removed 130 words of code, many of which are run multiple times. The biggest single improvement came from replacing

Code: Select all

          bm(l) = bm(l) >> 1
          bm(l).7 = ts.7
with

Code: Select all

          tb = bm(l)
          tb = tb >> 1
          tb.7 = ts.7
          bm(l) = tb
This saved 60 words which, for a 128x64 image are in a loop which is run 16 * 8 * 8 * 8 = 8192 times. This saves nearly half a million instruction executions....

I'd suggest trying something similar at first and using temporary variables rather than referencing arrays directly.
Simplifying the calculations you do inside the loop will also help and it might be worth trying replacing the const array reference with a calculation if that is possible.

There are other techniques such as using the FSR registers for linear memory access and the Table register for const access but try the above for a starter.

animo3d
Posts: 24
Joined: Sun Sep 18, 2011 6:02 am
Location: Monterrey Mexico

Re: code optimization help

Post by animo3d » Tue Jun 09, 2015 10:22 pm

thanks for the tip... I will try remove these references to arrays...

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: code optimization help

Post by Jerry Messina » Wed Jun 10, 2015 2:39 pm

What are the contents of the Transp() array?

const Transp(16) as byte = (??????)

Post Reply