Author Topic: Multithreaded Mandelbrot using 8th  (Read 288 times)

Offline jalih

  • Advocate
  • Posts: 111
Multithreaded Mandelbrot using 8th
« on: May 06, 2024, 09:44:55 PM »
Here is a multithreaded Mandelbrot program using 8 rendering threads + main GUI thread. Uses complex math for calculations.

Code: [Select]
needs nk/gui

libbin font/Roboto-Regular.ttf

font/Roboto-Regular.ttf font:new "font1" font:atlas! drop

600 constant WIDTH
600 constant HEIGHT

8 constant NUMTASKS

WIDTH HEIGHT img:new constant buffer

WIDTH 1.5 n:/ 40 n:+ constant x-axis
HEIGHT 2 n:/ constant y-axis
300 constant scale
50 constant iterations

: c:^  \ c n -- c
  >r dup c:abs r@ n:^ swap c:arg
  dup 2 a:close
  0 ( r@ n:* n:cos ) a:op!
  1 ( r> n:* n:sin ) a:op!
  swap >r ( r@ n:* ) a:map c:new rdrop ;
 
nullvar mand-task-ids

: mand-task  \ start-row end-row --
  ( drop
    (  drop
       0 0 c:new "z" t:!

       I x-axis n:- scale n:/
       J y-axis n:- scale n:/
       c:new dup "c" t:!

       c:>ri "y" t:! "x" t:!
       "y" t:@ 2 n:^ "y2" t:!
       "x" t:@ 0.25 n:- 2 n:^ "y2" t:@ n:+
       dup "x" t:@ 0.25 n:- n:+ n:* "y2" t:@ 4 n:/ n:<
       "x" t:@ n:1+ 2 n:^ "y2" t:@ n:+ 0.0625 n:< or !if
         ( "z" t:@ 2 c:^ "c" t:@ c:+ dup "z" t:!
           c:abs 2 n:> if
             765 n:* iterations n:/ dup>r 510 n:< !if
               255 255 r> 255 n:mod n:int 255 4 a:close "color" t:!
               break
             else
               r@ 255 n:< !if
                 255 r> 255 n:mod n:int 0 255 4 a:close "color" t:!
                 break
               else
                 r> 255 n:mod n:int 0 0 255 4 a:close "color" t:!
                 break
               then
             then
           else
             drop
             0 0 0 255 4 a:close "color" t:!
           then
         ) 0 iterations n:1- loop
         buffer lock J I "color" t:@ img:pix! unlock lock HEIGHT J n:- I "color" t:@ img:pix! unlock drop
       then
    ) 0 WIDTH n:1- loop
  null nk:do
  ) -rot loop ;

: start-tasks
  HEIGHT 2 n:/ NUMTASKS n:/mod 0 >r
  a:new ( r@ third n:r+ r@ n:1- 2 ' mand-task t:task-n a:push ) NUMTASKS n:1- times
  -rot n:+ r> tuck n:+ 2 ' mand-task t:task-n a:push mand-task-ids ! ;

: new-win
  {
    name: "main",
    wide: @WIDTH,
    high: @HEIGHT,
    resizable: true,
    title: "Mandelbrot"
  }
  nk:win ;

: main-render
  {
    title: "mandel",
    bg: "black",
    padding: [0,0],
    flags: [ @nk:WINDOW_NO_SCROLLBAR ]
  }

  nk:begin
    null 1 1 nk:layout-grid-begin
      0 1 0 1 nk:grid nk:rect>local nk:grid-push buffer lock nk:image buffer unlock drop
    nk:layout-grid-end
  nk:end ;

: app:main
  ' start-tasks w:is nk:rendering
  new-win ' main-render -1 nk:render-loop ;