Author Topic: ScriptBasic JIT  (Read 2613 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 3004
    • ScriptBasic Open Source Project
ScriptBasic JIT
« on: May 30, 2013, 07:18:03 PM »
Charles Pegge (OxygenBasic / DLLC author) has done it again and added JIT (Just-In-Time) function scripting, compiling and calling all at runtime. The following example is interesting as it shows DLLC supporting the JAPI  (Java Application Programming Interface) and using JIT for the Mandelbrot Set calculation. (76,800 pixel calculations)



The following code is using DLLC to interface with the JAPI DLL to produce the Mandelbrot Set.

Code: [Select]
' JAPI 2.0 DLLC

include "dllcinc.sb"

japi = dllfile("japi.dll")

j_start = dllproc(japi, "j_start i = ()")
j_frame = dllproc(japi, "j_frame i = (c * label)")
j_menubar = dllproc(japi, "j_menubar i = ( i obj)")
j_menu = dllproc(japi, "j_menu i = (i obj, c *label)")
j_menuitem = dllproc(japi, "j_menuitem i = (i obj, c *label)")
j_canvas = dllproc(japi, "j_canvas i = (i obj, i width , i height)")
j_setpos = dllproc(japi, "j_setpos (i obj, i xpos, i ypos)")
j_pack = dllproc(japi, "j_pack (i obj)")
j_show = dllproc(japi, "j_show (i obj)")
j_getaction = dllproc(japi, "j_getaction i = ()")
j_nextaction = dllproc(japi, "j_nextaction i = ()")
j_setcolor = dllproc(japi, "j_setcolor (i obj, i r, i g, i b)")
j_drawpixel = dllproc(japi, "j_drawpixel (i obj, i x, i y)")
j_quit = dllproc(japi, "j_quit ()")

CONST J_TRUE = 1
CONST J_FALSE = 0


xstart = -1.8
xend   =  0.8
ystart = -1.0
yend   =  1.0

hoehe  = 240
breite = 320

if (dllcall(j_start) = J_FALSE) then
  print("JAPI interface failed to start.\n")
  end
endif

jframe  = dllcall(j_frame,"JAPI 2.0 DLLC")
menubar = dllcall(j_menubar,jframe)
jfile   = dllcall(j_menu,menubar,"File")
calc    = dllcall(j_menu,menubar,"Calc")
quit    = dllcall(j_menuitem,jfile,"Quit")
start   = dllcall(j_menuitem,calc,"Start")
jstop   = dllcall(j_menuitem,calc,"Stop")

canvas  = dllcall(j_canvas,jframe,breite,hoehe)
dllcall(j_setpos,canvas,10,60)
dllcall(j_pack,jframe)
dllcall(j_show,jframe)

obj = 0
do_work = 0

while((obj <> jframe) and (obj <> quit))

    if(do_work = 1) then
        obj = dllcall(j_getaction)
    else
        obj = dllcall(j_nextaction)
    endif      

    if(obj = start) then
        x = -1
        y = -1
        do_work = 1
        st = dllsecs()
    endif

    if(obj = jstop) then
        do_work = 0
    endif
    
    if(do_work = 1) then
        x = (x+1) % breite
       if(x = 0) then
            y = (y+1) % hoehe
       endif
       if((x = breite-1) and (y = hoehe-1)) then
            do_work = 0
            PRINT format("%g",dllsecs() - st),"\n"
        else
            zre = xstart + x*(xend-xstart)/breite
            zim = ystart + y*(yend-ystart)/hoehe
            it = mandel(zre,zim,512)
            dllcall(j_setcolor,canvas,it*11,it*13,it*17)
            dllcall(j_drawpixel,canvas,x,y)
        endif
    endif

wend

dllcall(j_quit)


function mandel(zre,zim,maxiter)
    mx = 0.0
    my = 0.0
    iter=0
    betrag=0.0
 
    while ((iter < maxiter) and (betrag < 4.0))
        iter = iter+1
        tmp = mx*mx-my*my+zre
        my = 2*mx*my+zim
        mx = tmp
        betrag = (mx*mx + my*my)
    wend
    mandel=iter
end function

This version uses the new JIT compiling feature of DLLC with the mandel() function compiled at runtime.

Code: [Select]
' JAPI 2.0 DLLC JIT

include "dllcinc.sb"

oxy = dllfile("/sb22/modules/oxygen.dll")

o2_basic = dllproc( oxy, "o2_basic i =(c*source) " )
o2_exec  = dllproc( oxy, "o2_exec  i =(i call)   " )
o2_error = dllproc( oxy, "o2_error c*=()         " )
o2_errno = dllproc( oxy, "o2_errno i =()         " )
o2_len   = dllproc( oxy, "o2_len   i =()         " )
o2_mode  = dllproc( oxy, "o2_mode     (i mode)   " )

dllcall(o2_mode,1)

src = """
extern
function mandel(float zre,zim,sys maxiter) as sys
    float mx,my,betrag
    sys iter
 
    while iter < maxiter and betrag < 4.0
        iter = iter+1
        tmp = mx*mx-my*my+zre
        my = 2*mx*my+zim
        mx = tmp
        betrag = (mx*mx + my*my)
    wend
    return iter
end function

sub finish()
  terminate
end sub

function link(sys n) as sys
  select n
    case 0
      return @finish
    case 1
      return @mandel
  end select
end function

end extern

addr link
"""

dllcall(o2_basic, src)
dfn = dllcall(o2_exec,0)
mandel = dllproc(dfn,"mandel i = (f zre, f zim, i maxiter)", dllcald(dfn, 1))
finish = dllproc(dfn,"finish ()", dllcald(dfn, 0))

japi = dllfile("japi.dll")

j_start = dllproc(japi, "j_start i = ()")
j_frame = dllproc(japi, "j_frame i = (c * label)")
j_menubar = dllproc(japi, "j_menubar i = ( i obj)")
j_menu = dllproc(japi, "j_menu i = (i obj, c *label)")
j_menuitem = dllproc(japi, "j_menuitem i = (i obj, c *label)")
j_canvas = dllproc(japi, "j_canvas i = (i obj, i width , i height)")
j_setpos = dllproc(japi, "j_setpos (i obj, i xpos, i ypos)")
j_pack = dllproc(japi, "j_pack (i obj)")
j_show = dllproc(japi, "j_show (i obj)")
j_getaction = dllproc(japi, "j_getaction i = ()")
j_nextaction = dllproc(japi, "j_nextaction i = ()")
j_setcolor = dllproc(japi, "j_setcolor (i obj, i r, i g, i b)")
j_drawpixel = dllproc(japi, "j_drawpixel (i obj, i x, i y)")
j_quit = dllproc(japi, "j_quit ()")

CONST J_TRUE = 1
CONST J_FALSE = 0


xstart = -1.8
xend   =  0.8
ystart = -1.0
yend   =  1.0

hoehe  = 240
breite = 320

if (dllcall(j_start) = J_FALSE) then
  print("JAPI interface failed to start.\n")
  end
endif

jframe  = dllcall(j_frame,"JAPI 2.0 DLLC JIT")
menubar = dllcall(j_menubar,jframe)
jfile   = dllcall(j_menu,menubar,"File")
calc    = dllcall(j_menu,menubar,"Calc")
quit    = dllcall(j_menuitem,jfile,"Quit")
start   = dllcall(j_menuitem,calc,"Start")
jstop   = dllcall(j_menuitem,calc,"Stop")

canvas  = dllcall(j_canvas,jframe,breite,hoehe)
dllcall(j_setpos,canvas,10,60)
dllcall(j_pack,jframe)
dllcall(j_show,jframe)

obj = 0
do_work = 0

while((obj <> jframe) and (obj <> quit))
    if(do_work = 1) then
        obj = dllcall(j_getaction)
    else
        obj = dllcall(j_nextaction)
    endif      

    if(obj = start) then
        x = -1
        y = -1
        do_work = 1
        st = dllsecs()
    endif

    if(obj = jstop) then
        do_work = 0
    endif
    
    if(do_work = 1) then
        x = (x+1) % breite
       if(x = 0) then
            y = (y+1) % hoehe
       endif
       if((x = breite-1) and (y = hoehe-1)) then
            do_work = 0
            PRINT format("%g",dllsecs() - st),"\n"
        else
            zre = xstart + x*(xend-xstart)/breite
            zim = ystart + y*(yend-ystart)/hoehe
            it = dllcall(mandel,zre,zim,512)
            dllcall(j_setcolor,canvas,it*11,it*13,it*17)
            dllcall(j_drawpixel,canvas,x,y)
        endif
    endif
wend

dllcall(Finish)
dllcall(j_quit)
dllfile

When the menu start option is clicked I record the time and print the results when the last pixel is displayed of the Mandelbrot Set.

ScriptBasic
C:\SB22\japi_dllc>scriba mandel_dllc.sb
56.9223

C:\SB22\japi_dllc>

ScriptBasic JIT

C:\SB22\japi_dllc>scriba mandel_dllc2.sb
17.608

C:\SB22\japi_dllc>

« Last Edit: May 30, 2013, 11:22:12 PM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3004
    • ScriptBasic Open Source Project
Re: ScriptBasic JIT
« Reply #1 on: June 01, 2013, 01:38:08 AM »
I converted the JAPI Mandelbrot Set to Simple Window to compare the speed of the two libraries.



Code: OxygenBasic
  1. ' Simple Window DLLC JIT
  2.  
  3. include "dllcinc.sb"
  4.  
  5. oxy = dllfile("/sb22/modules/oxygen.dll")
  6.  
  7. o2_basic = dllproc( oxy, "o2_basic i =(c*source) " )
  8. o2_exec  = dllproc( oxy, "o2_exec  i =(i call)   " )
  9. o2_error = dllproc( oxy, "o2_error c*=()         " )
  10. o2_errno = dllproc( oxy, "o2_errno i =()         " )
  11. o2_len   = dllproc( oxy, "o2_len   i =()         " )
  12. o2_mode  = dllproc( oxy, "o2_mode     (i mode)   " )
  13.  
  14. dllcall(o2_mode,1)
  15.  
  16. src = """
  17. extern
  18. function mandel(float zre,zim,sys maxiter) as sys
  19.     float mx,my,betrag
  20.     sys iter
  21.  
  22.     while iter < maxiter and betrag < 4.0
  23.         iter = iter+1
  24.         tmp = mx*mx-my*my+zre
  25.         my = 2*mx*my+zim
  26.         mx = tmp
  27.         betrag = (mx*mx + my*my)
  28.     wend
  29.     return iter
  30. end function
  31.  
  32. sub finish()
  33.   terminate
  34. end sub
  35.  
  36. function link(sys n) as sys
  37.   select n
  38.     case 0
  39.       return @finish
  40.     case 1
  41.       return @mandel
  42.   end select
  43. end function
  44.  
  45. end extern
  46.  
  47. addr link
  48. """
  49.  
  50. dllcall(o2_basic, src)
  51. dfn = dllcall(o2_exec,0)
  52. mandel = dllproc(dfn,"mandel i = (f zre, f zim, i maxiter)", dllcald(dfn, 1))
  53. finish = dllproc(dfn,"finish ()", dllcald(dfn, 0))
  54.  
  55. sw = dllfile("sw.dll")
  56.  
  57. Window = dllproc(sw, "Window i = (i width, i height, i mode)")
  58. SetCaption = DLLC_Proc(sw, "SetCaption i = (c *capText)")
  59. SetPixel = dllproc(sw, "SetPixel i = (i xPos, i yPos, i color)")
  60. RGB = dllproc(sw, "RGB i = (i rValue, i gValue, i bValue)")
  61. Redraw = DLLC_Proc(sw, "Redraw ( )")
  62. WaitKey = dllproc(sw, "WaitKey i = ( )")
  63. Quit = DLLC_Proc(sw, "Quit i = ( )")
  64.  
  65.  
  66. xstart = -1.8
  67. xend   =  0.8
  68. ystart = -1.0
  69. yend   =  1.0
  70.  
  71. hoehe  = 240
  72. breite = 320
  73.  
  74. dllcall(Window,320,240,1)
  75. dllcall(SetCaption,"SB SW DLLC JIT")
  76.  
  77. st = dllsecs()
  78.  
  79. x = -1
  80. y = -1
  81.  
  82. REPEAT
  83.   x = (x+1) % breite
  84.   if(x = 0) then y = (y+1) % hoehe
  85.   zre = xstart + x*(xend-xstart)/breite
  86.   zim = ystart + y*(yend-ystart)/hoehe
  87.   it = dllcall(mandel,zre,zim,512)
  88.   dllcall(SetPixel,x, y, dllcall(RGB,it*11,it*13,it*17))
  89.   dllcall(Redraw)
  90. UNTIL ((x = breite-1) and (y = hoehe-1))
  91. PRINT format("%g",dllsecs() - st),"\n"
  92. dllcall(WaitKey)
  93.  
  94. dllcall(Finish)
  95. dllcall(Quit)
  96. dllfile
  97.  

C:\SB22\japi_dllc>scriba swmandeldllc.sb
5.57576

C:\SB22\japi_dllc>

If I remove the Redraw() function and wait until the it's done to refresh the screen.

C:\SB22\japi_dllc>scriba swmandeldllc.sb
1.05691

C:\SB22\japi_dllc>

This is stock SB with no JIT assist.

Code: OxygenBasic
  1. ' Simple Window DLLC
  2.  
  3. include "dllcinc.sb"
  4.  
  5. sw = dllfile("sw.dll")
  6.  
  7. Window = dllproc(sw, "Window i = (i width, i height, i mode)")
  8. SetCaption = DLLC_Proc(sw, "SetCaption i = (c *capText)")
  9. SetPixel = dllproc(sw, "SetPixel i = (i xPos, i yPos, i color)")
  10. RGB = dllproc(sw, "RGB i = (i rValue, i gValue, i bValue)")
  11. Redraw = DLLC_Proc(sw, "Redraw ( )")
  12. WaitKey = dllproc(sw, "WaitKey i = ( )")
  13. Quit = DLLC_Proc(sw, "Quit i = ( )")
  14.  
  15. function mandel(zre,zim,maxiter)
  16.     mx = 0.0
  17.     my = 0.0
  18.     iter=0
  19.     betrag=0.0
  20.  
  21.     while ((iter < maxiter) and (betrag < 4.0))
  22.         iter = iter+1
  23.         tmp = mx*mx-my*my+zre
  24.         my = 2*mx*my+zim
  25.         mx = tmp
  26.         betrag = (mx*mx + my*my)
  27.     wend
  28.     mandel=iter
  29. end function
  30.  
  31. xstart = -1.8
  32. xend   =  0.8
  33. ystart = -1.0
  34. yend   =  1.0
  35.  
  36. hoehe  = 240
  37. breite = 320
  38.  
  39. dllcall(Window,320,240,1)
  40. dllcall(SetCaption,"SB SW DLLC")
  41.  
  42. st = dllsecs()
  43.  
  44. x = -1
  45. y = -1
  46.  
  47. REPEAT
  48.   x = (x+1) % breite
  49.   if(x = 0) then y = (y+1) % hoehe
  50.   zre = xstart + x*(xend-xstart)/breite
  51.   zim = ystart + y*(yend-ystart)/hoehe
  52.   it = mandel(zre,zim,512)
  53.   dllcall(SetPixel,x, y, dllcall(RGB,it*11,it*13,it*17))
  54. UNTIL ((x = breite-1) and (y = hoehe-1))
  55. dllcall(Redraw)
  56. PRINT format("%g",dllsecs() - st),"\n"
  57. dllcall(WaitKey)
  58.  
  59. dllcall(Quit)
  60. dllfile
  61.  

With Redraw() in the loop.

C:\SB22\japi_dllc>scriba swnojit.sb
45.0972

C:\SB22\japi_dllc>

Wait until the end to display the results.

C:\SB22\japi_dllc>scriba swnojit.sb
39.637

C:\SB22\japi_dllc>
« Last Edit: June 01, 2013, 01:45:32 AM by JRS »