Announcement

Collapse
No announcement yet.

PBWin.9 Speedy Power^2 or Power^3 calculation

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PBWin.9 Speedy Power^2 or Power^3 calculation

    When using PBWin for geometry calculation, we often deal with formula like
    y = a + b*x² or y = a + b*x + c*x³

    Calculation written in PBWin 'yval# = aval# + bval# * xval#^2' seems compiled as power function when using only FMUL for FPU should be much faster.

    So I write 'yval# = aval# + bval# * xval# * xval#' but compiled program will access the same variable memory two times when xval# is already in the FPU registers.

    What is your thinking about a Power2() and Power3() function ?
    (forwarded to [email protected])
    Marc - France :-)

  • #2
    You can allocate up to 4 variables per sub or function to FPU registers thus no need for extra memory accesses in your second formular

    Comment


    • #3
      Marc,
      it saves some time, but not a lot.

      If you really need to save every last clk cycle in your FP calculations then you should look into learning ASM. Once you get the hang of it then it's quite easy to use for straightforward calculations such as this.

      Paul.

      Comment


      • #4
        Originally posted by Paul Dixon View Post
        ... you should look into learning ASM...
        Paul.
        Thanks for your reply, Paul. I've done some ASM coding for integer. I'm still new for FPU, FPU registers, access to local variables. I still need to learn and test.
        Marc - France :-)

        Comment


        • #5
          Marc,
          the FPU is slightly unusual in that it works with a stack so you can't use the registers interchangeably as you would with integer arithmetic.
          There are 8 FPU registers called st(0), st(1), st(2) ... st(7)
          ST(0) is the top of stack and takes part in most FP calculations.

          That's enough explaining, let's look at a simple example or 2.

          To square a number
          Code:
          x= 3
          !fld x               'load x onto the stack, st(0)=x
          !fmul st(0),st(0)    'multiply top of stack by itself, st(0)=st(0)*st(0) = x^2
          !fstp x              'return value to x and pop the stack so it's empty (the final "p" of fstp does that)
          PRINT x
          That wasn't too hard, was it?

          To cube a number
          Sometimes, especially when starting out, it's helpful to keep a list of what is in each register on the stack
          Code:
          x= 3
          '     FPU register   st(0)      st(1)       st(2)   ...and the others
          !fld x               'x         empty       empty  'load x onto the stack
          !fld st(0)           'x         x           empty  'load top of stack onto stack, i.e. duplicate st(0)
          !fmul st(0),st(0)    'x^2       x           empty  'multiply st(0) by itself and put result in st(0)
          !fmulp st(1),st(0)   'x^3       empty       empty  'multiply st(1) by st(0), result in st(1) but then pop the stack so the x^2 in st(0)is removed leaving x^3 in st(0)
          !fstp x              'empty     empty       empty  'store the result in x and pop the stack to leave it clean.
          PRINT x
          Still not too hard?
          Note that you don't need to worry about how to access which variable. You just refer to it by name. The only exception to this is if the variable was passed to you as a parameter in a SUB/FUNCTION call.


          And while we're at it, how about a third example.
          You used the equation:
          Code:
           y = a + b*x + c*x³
          So let's do that in ASM.
          Code:
          '      FPU registers  st0           st1         st2    st3
          !fld x                'x
          !fld st(0)            'x             x
          !fmul st(0),st(1)     'x^2           x
          !fmul st(0),st(1)     'x^3           x
          !fld c                'c             x^3         x
          !fmulp st(1),st(0)    'c*x^3         x
          !fld b                'b             c*x^3       x
          !fmulp st(2),st(0)    'c*x^3         b*x
          !faddp st(1),st(0)    'b*x+c*x^3
          !fld a                'a             b*x+c*x^3
          !faddp st(1),st(0)    'a+b*x+c*x^3
          !fstp y               'empty
          
          PRINT "y=";y
          A few things to point out.
          1) the first operand is the destination so:
          Code:
          !fmul st(1),st(0)
          multiplies ST(1) and st(0) and puts the result in st(1)

          2) if we add a p to the end of the opcode:
          Code:
          !fmulp st(1),st(0)
          then after the multiply and after the result is written to st(1) then the stack is popped and the current st(0) is discarded and all other registers shuffle up one place so the result actually ends up in st(0) after the pop.

          3) I advise you to use
          Code:
          #REGISTER NONE
          if you're doing ASM until you get used to it otherwise you'll keep getting compile errors where the compiler tries to allocate stuff to a FP register for you and can't then load values from memory as they aren't actually in memory.

          You can get a copy of the Intel Programmers's Reference manual from here:
          http://developer.intel.com/design/pe...als/243191.htm

          Read through the list of opcodes starting with F to find all the FPU opcodes and what they do.

          Paul.

          Comment


          • #6
            Paul, Thanks for your ASM lessons for FPU coding
            Marc - France :-)

            Comment

            Working...
            X