Faster ^ and EXP

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
k6sti
Posts: 19
Joined: Feb 14, 2019 14:31

Faster ^ and EXP

Post by k6sti »

These substitutes for the FreeBASIC ^ power function and EXP exponential function reduce execution time. They replace the FRNDINT and FSCALE instructions with faster equivalents. On a fourth-generation Intel processor, ^ took 60% as long and EXP 70% as long as the FreeBASIC functions. The code should run on a 486.

The code uses NASM assembler syntax. Include the Nokeyword option and EXP declaration in the BASIC program since FreeBASIC normally generates inline code for this function. Use the FreeBASIC -a command line option to link the object code to your program.

I used 32-bit FreeBASIC in QB mode to test the code in Windows 10.

Code: Select all

;       Assemble with NASM

        global _pow, _EXP

        section .data align=16

pow     dw      0,0,0,8000h,0           ; 80-bit floating point template

        section .text align=16

;       Faster ^ replacement

_pow:   fld     qword [esp+12]          ; y         x^y = 2^(y*log2(x))
        fld     qword [esp+4]           ; x y           = 2^(int+frac)
        fyl2x                           ; y*log2(x)
exp:    fist    word [pow+8]            ; int+frac
        fisub   word [pow+8]            ; frac
        add     word [pow+8],3fffh      ;           exponent bias
        js      uflo
        f2xm1                           ; 2^frac-1
        fld     tword [pow]             ; 2^int 2^frac-1
        fmul    st1,st0                 ; 2^int 2^(int+frac)-2^int
        faddp                           ; 2^(int+frac)
        ret
uflo:   fstp    st0                     ;           underflow
        fldz                            ; 0
        ret

;       Option Nokeyword EXP
;       DECLARE FUNCTION EXP# CDecl (y#)
;       Faster EXP replacement

        align 16

_EXP:   mov     eax,[esp+4]
        fldl2e                          ; log2(e)
        fmul    qword [eax]             ; y*log2(e)
        jmp     exp
Post Reply