Announcement

Collapse
No announcement yet.

MAT is slower than direct multiplication

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

  • MAT is slower than direct multiplication

    ' MAT is slower than direct multiplication
    '
    ' To my surprise MAT seems to calculate slower than direct multiplication
    ' in this particular example. Is this a generally recognized fact?
    ' If so what is the explanation?
    Code:
    ' MAT is slower than direct multiplication
    '
    ' To my surprise MAT seems to calculate slower than direct multiplication
    ' in this particular example. Is this a generally recognized fact?
    ' If so what is the explanation?
    
    #COMPILE EXE
    #REGISTER NONE
    #DIM ALL
    '
    #INCLUDE "WIN32API.INC"
    '
    ' The function below is taken from my code in this thread:
    ' http://www.powerbasic.com/support/pbforums/showthread.php?t=24258
    FUNCTION CurrentTimePointInSeconds AS DOUBLE
        ' This function returns the number of seconds since midnight
        ' as a Double-precision floating-point value.
        STATIC PerfFreq AS QUAD, Res AS LONG, Prec AS LONG, First AS LONG, TimeCorrection AS DOUBLE
        LOCAL t1 AS QUAD, ta AS DOUBLE
        '
        IF ISFALSE First THEN
            ' Get, in counts per second, the current performance-counter frequency
            ' if supported by your hardware.
            Res = QueryPerformanceFrequency(PerfFreq)
            '
            ' Determine Precision
            IF Res THEN
                Prec = CEIL(LOG10(PerfFreq))
                QueryPerformanceCounter t1
                ta = ROUND(CDBL(t1) / CDBL(PerfFreq), Prec)
                ' Find time correction to obtain number of seconds past midnight.
                TimeCorrection = TIMER - ta
                '
                FUNCTION = ta + TimeCorrection
                First = %TRUE : EXIT FUNCTION
            ELSE
                Prec = 2 ' Precision of TIMER is only about 1/18th of a second.
            END IF
            First = %TRUE
        END IF
        ' Measure current time
        IF Res THEN ' if possible use this:
            QueryPerformanceCounter t1
            FUNCTION = ROUND(CDBL(t1) / CDBL(PerfFreq), Prec) + TimeCorrection
        ELSE        ' else use the built-in timer
            ta = TIMER
            FUNCTION = ROUND(ta, Prec)
        END IF
        '
    END FUNCTION
    '
    FUNCTION PBMAIN
        LOCAL t1 AS DOUBLE, t2 AS DOUBLE
        LOCAL tx AS STRING
        LOCAL i&,j&,k&, m&
        LOCAL fa AS DOUBLE
    
        DIM B(1 TO 3) AS LOCAL SINGLE         ' Input vector
        DIM C(1 TO 4, 1 TO 3) AS LOCAL SINGLE ' Transformation matrix
        DIM A(1 TO 4) AS LOCAL SINGLE         ' Resulting output vector
        '
        DATA 4.1256, 0.3879, 1.35566              : ' vector B
      '  '
        tx = "vector B() = " + $CRLF
        tx= tx +$CRLF+$CRLF + "Matrix C() = " + $CRLF
        DATA 1.34566, -3.2345, 0.23445, 2.2333    : ' matrix C - row 1
        DATA 2.27654, 5.98765, 3.12334, -1.54333  : ' matrix C - row 2
        DATA 4.23555, 6.23444, 1.25552, 8.6654    : ' matrix C - row 3
        '
        ' Read arrays
        '
        tx = "vector B() = " + $CRLF
    
        FOR i = 1 TO 3
            INCR k
            B(i) = VAL(READ$(k))
            tx = tx + STR$(B(i))+"  "
        NEXT
        tx= tx +$CRLF+$CRLF + "Matrix C() = " + $CRLF
    
        FOR i = 1 TO 3
            FOR j = 1 TO 4
                INCR k
                C(j,i) = VAL(READ$(k))
                tx=tx+STR$(C(j,i))+"  "
            NEXT
            tx=tx+$CRLF
        NEXT
        '
        tx = tx +$CRLF+$CRLF +"A() = C() * B()"
    
        ' Do direct calculation
        '
        ' Measure first time
        t1 = CurrentTimePointInSeconds
    
      FOR m = 1 TO 1000000 ' Do calculation 1 mill. times
        FOR j = 1 TO 4 ' Column
            A(j) = 0!
            FOR k = 1 TO 3 ' Row
                A(j) = A(j) + B(k) * C(j,k)
            NEXT k
        NEXT j
      NEXT
    
        ' Measure second time
        t2 = CurrentTimePointInSeconds
    
        tx = tx +$CRLF+$CRLF+"Direct Calculation:"+$CRLF+$CRLF+"Time 1: " + FORMAT$(t1) + " seconds past midnight" + $CRLF
        tx = tx + "Time 2: " + FORMAT$(t2) + " seconds past midnight" + $CRLF + $CRLF
        tx = tx + "Time interval in seconds is: " + FORMAT$(t2 - t1, "######.#########")
        fa = t2 - t1
        '
        '
        t1 = CurrentTimePointInSeconds
        '
      FOR m = 1 TO 1000000 ' Do calculation 1 mill. times
        '
        ' Do calculation using MAT
        '
        MAT A() = C() * B()
    
      NEXT
        t2 = CurrentTimePointInSeconds
        '
        tx = tx + $CRLF+$CRLF+$CRLF+"MAT Calculation:"+$CRLF+$CRLF+"Time 1: " + FORMAT$(t1) + " seconds past midnight" + $CRLF
        tx = tx + "Time 2: " + FORMAT$(t2) + " seconds past midnight" + $CRLF + $CRLF
        tx = tx + "Time interval in seconds is: " + FORMAT$(t2 - t1, "######.#########")
        fa = (t2 - t1)/fa
        tx=tx+$CRLF+$CRLF+"Thus MAT is "+FORMAT$(fa, "######.###")+" times slower that direct calculation."
        MSGBOX tx, %MB_ICONINFORMATION, "Multiplication Time"
        '
    END FUNCTION

  • #2
    Just for the heck of it I ran this.

    On my system one run "inline" was .28 sec, MAT was .41 Sec. Thirteen one-hundreths of a second difference for one million interations.
    • Who cares about the time difference?
    • Your inline code hard-codes the ranges of the arrays (LBOUND:UBOUND) whereas MAT has to read them and work with them as variables rather then compile-time constants; that is, your code is not comparing applies for apples.
    • You could probably save time by first reading the help file and using the more efficient zero-based arrays instead of non-zero-based arrays. That is, your choice of syntax to actually effect the multiplication is only one factor in your run-time performance.
    • For that matter, you could speed up the "inline" version a lot by using incremented pointer variables or even [offset] pointer variables instead of needlessly hitting the array engine three times for each arithmetic operation.

    MCM
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Thanks. You gave me some good ideas.

      Comment

      Working...
      X