Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:13 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Fractal Images

     Page 1 of 3    
Author Message
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 03:00am 15 Oct 2015
Copy link to clipboard 
Print this post

I have had a bit of fun experimenting with some fractal image programs on the Micromite with a colour LCD.

These were originally posted by Loki for the original monochrome Maximite back in 2012.

Julia set fractal on a 2.2" ILI9341 LCD:


Mandelbrot set fractal on a 7" SSD1963 LCD:


The programs (modified to run on the Micromite or Micromite Plus) are listed below. Be warned, they can take a LONG time to finish:

'JULIA.BAS - Draws Julia set fractal images
'by loki

Dim As Integer MAXIT, COUNT
Cls

'Specify initial values
RealOffset = -1.30
ImaginOffset = -0.95
'------------------------------------------------*
'Set the Julia set constant [eg C = -1.2 + 0.8i]
CRealVal = -0.78
CImagVal = -0.20
'------------------------------------------------*
MAXIT=80 'max iterations
GAP = MM.VRes / MM.HRes
SIZE = 2.50
XDelta = SIZE / MM.HRes
YDelta = (SIZE * GAP) / MM.VRes

'Loop processing - visit every pixel
For X = 0 To (MM.HRes - 1)
CX = X * Xdelta + RealOffset
For Y = 0 To (MM.VRes - 1)
CY = Y * YDelta + ImaginOffset
Zr = CX
Zi = CY
COUNT = 0
'Begin Iteration loop
Do While (( COUNT <= MAXIT ) And (( Zr * Zr + Zi * Zi ) < 4 ))
new_Zr = Zr * Zr - Zi * Zi + CRealVal
new_Zi = 2 * Zr * Zi + CImagVal
Zr = new_Zr
Zi = new_Zi
COUNT = COUNT + 1
Loop
PIXEL X, Y, (COUNT and 4) * 4177920 + (COUNT and 2) * 32640 + (COUNT and 1) * 255)
Next Y
Next X


'MANDELBROT.BAS - Draws mandelbrot set fractal images
' by loki

Dim As Integer MAXIT, COUNT

'Specify initial values
RealOffset = -2.0
ImaginOffset = -0.85
MAXIT=70 'max iterations

GAP = MM.VRES / MM.HRES
SIZE = 2.8
XDelta = SIZE / MM.HRES
YDelta = (SIZE * GAP) / MM.VRES
CLS

'Loop processing - visit every pixel in screen area and base colour of pixel
' on the number of iterations required to escape boundary conditions
' If count hits max iterations then pixel hasn't escaped and is part of the set (the 'inner sea')
FOR X = 0 TO (MM.HRES - 1)
Cx = X * Xdelta + RealOffset
FOR Y = 0 TO (MM.VRES - 1)
Cy = Y * YDelta + ImaginOffset
Zr = 0.0
Zi = 0.0
COUNT = 0
'Begin Iteration loop, checking boundary conditions on each loop
DO WHILE (( COUNT <= MAXIT ) AND (( Zr * Zr + Zi * Zi ) <= 4 ))
new_Zr = Zr * Zr - Zi * Zi + Cx
new_Zi = 2 * Zr * Zi + Cy
Zr = new_Zr
Zi = new_Zi
COUNT = COUNT + 1
LOOP
PIXEL X, Y, (COUNT and 4) * 4177920 + (COUNT and 2) * 32640 + (COUNT and 1) * 255)
NEXT Y
NEXT X

Geoff Graham - http://geoffg.net
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2944
Posted: 05:10am 15 Oct 2015
Copy link to clipboard 
Print this post

The bottom image is the first thing I tried on a 2.4" SPI display when matherp's code first came out.

It would be interesting to see the speed difference on a MM+ with a 800x480 SSD display (something else just added to my to-do list!)

Geoff: How long did the first image take to create (and on what 'spec' MM)??
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1593
Posted: 06:13am 15 Oct 2015
Copy link to clipboard 
Print this post

Thanks Geoff! Something to play with ...

JULIA.BAS takes 519688ms on a uM2/2.4 LCD (CPU 48).

Maybe it needs some CFunction optimizing ...

Regards
MichaelEdited by twofingers 2015-10-16
causality ≠ correlation ≠ coincidence
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 03:41pm 15 Oct 2015
Copy link to clipboard 
Print this post

The first image (Julia) took about 10 minutes (as reported by twofingers) on a MM MkII with a 2.2" ILI9341 LCD. The second using a MM+ (100MHz) on a 7" SSD1963 LCD took an hour or two (I did not time it).

The more pixels the longer it takes.
Geoff Graham - http://geoffg.net
 
loki
Newbie

Joined: 23/12/2011
Location: Australia
Posts: 7
Posted: 06:41pm 18 Oct 2015
Copy link to clipboard 
Print this post

Thank you Geoff for your work on these. It gave me a warm and fuzzy feeling knowing others are having a bit of fun with fractals .

I've been offline the last few years due to my wife being very ill with breast cancer, and in fact she passed away 12 mths ago so I haven't had a lot of time for hobbies, but I'm slowly getting back in to it. I have one or two projects in mind for the maximite/micromite and if they succeed will share them on the backshed.

I'd like to take this oppurtunity to thank the backshed and all of the contributors to it, as it has helped me to avoid becoming depressed as I've followed the various discussions and projects and kept me interested in others, and what they're working on.

In the meantime I've been working on a Windows fractal program in C# that was until recently using the SetPixel() command to colour each pixel. I've been able to speed things up by writing the pre-prepared array of colour bytes directly to the bitmap memory location, then calling the Invalidate() method on the picture box control (that has the bitmap bound to it), which causes Windows to invalidate the entire surface of the control thus forcing it to be redrawn.

Don't know if this approach could be used on the mites or not. Is video memory directly accessible in any way, rather than use the PIXEL command? Is it possible to create a new api in mmbasic that would be analagous to microsoft's DirectX api?

thanks again
cheers
rob (loki)


 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 11:44pm 18 Oct 2015
Copy link to clipboard 
Print this post

  loki said  Don't know if this approach could be used on the mites or not. Is video memory directly accessible in any way, rather than use the PIXEL command?

In the Colour Maximite you can write direct to the video memory buffer and you can get the address of this buffer using PEEK.

In the Micromites each pixel is sent over a SPI or parallel bus to the display which buffers it there. But, when experimenting with your programs I found that the limitation was the speed of the interpreter, not the display. I bet that it would be the same even if you were writing in C

In the Micromite you can load C routines using the CSub/CFunction facility. It is not an easy environment (eg, it is difficult using floats) but it would be fast.

Geoff
Geoff Graham - http://geoffg.net
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1132
Posted: 08:33pm 20 Oct 2015
Copy link to clipboard 
Print this post

Fascinating. I do a certain amount of embedded programming, often on 8 and 16 bit PICs. With their limited cpu power, attention must be paid to coding efficiency. Complex math is to be avoided, although for some chips, multiplication isn't too costly. So I looked at the sample code above, saw that certain multiplications were performed twice and wanted to see if the speed would change if the multiplications were performed once and the results re-used.

Here's what I did to the Julia.BAS program:
'Loop processing - visit every pixel
For X = 0 To (MM.HRes - 1)
CX = X * Xdelta + RealOffset
For Y = 0 To (MM.VRes - 1)
CY = Y * YDelta + ImaginOffset
Zr = CX
Zi = CY
ZZrr = Zr * Zr '**************** added
ZZii = Zi * Zi '**************** added
COUNT = 0
'Begin Iteration loop
DO '**************** changed loop type
'Do While (( COUNT <= MAXIT ) And (( Zr * Zr + Zi * Zi ) < 4 ))
'new_Zr = Zr * Zr - Zi * Zi + CRealVal
new_Zr = ZZrr - ZZii + CRealVal '**************** changed
new_Zi = 2 * Zr * Zi + CImagVal
Zr = new_Zr
Zi = new_Zi
COUNT = COUNT + 1
ZZrr = Zr * Zr '**************** added
ZZii = Zi * Zi '**************** added
'Loop '**************** changed loop type
LOOP until ((COUNT > MAXIT) or (( ZZrr + ZZii ) > 4 ))
PIXEL X, Y, (COUNT and 4) * 4177920 + (COUNT and 2) * 32640 + (COUNT and 1) * 255)
Next Y
Next X
Yup, it changed. It actually got slower! The original took 5:50 on my MM+, my changed code took 6:50, a whole minute slower. Hmmm.

OK, a quick test. I moved 2 comment lines that I added outside the DO LOOP UNTIL. That took off 10 seconds! All, right, next I removed every comment I had added. That took off another 13 seconds, down to 6:27. But that is still a long way to go to get back to 5:50! Wow. Next I'll try reducing my modified program down to the same number of lines in the working loop as the orignal...

=========================
Rob, best wishes.
Visit Vegipete's *Mite Library for cool programs.
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2944
Posted: 08:59pm 20 Oct 2015
Copy link to clipboard 
Print this post

@vegipete

Something that immediately sprung to mind while reading your post was the fact that in some 'old' versions of BASIC that I have used, program execution was improved by using short(er) variable names. This use to really help in most scenarios (although debugging then became a bit trickier).

I'm guessing things are 'tokenised' in MMBasic, but will raise the question anyway: will using single-letter variable names result in a faster running program??

WW
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 01:00am 21 Oct 2015
Copy link to clipboard 
Print this post

This was drawn much much faster - 10 seconds





I've converted the JULIA code to a CSUB as an exercise.

This allows you to set the four parameters CRealVal, CImagVal, RealOffset, ImaginOffset in the call to the CSUB. Note that because of a limitation in CFunctions and CSUBs you have to call JULIA with variables rather than literals.

In the code I've included all the example parameters from loki's original post and the program steps through each one in turn taking about 10 seconds each on a ILI9341 driven by a MM+.

The code should work on any Micromite with any of the supported display types

I would like to increase the colour resolution by altering the way the RGB code is constructed in the DrawPixel statement but so far my attempts have failed - any suggestions appreciated.

[code]
OPTION EXPLICIT
OPTION DEFAULT NONE
DIM FLOAT RealOffset = -1.30 ,ImaginOffset = -0.95, CRealVal ,CImagVal
DIM INTEGER i,NPatterns=13
DATA -0.71,0.35
DATA -0.64,0.42
DATA -0.61,0.44
DATA -0.59,0.46
DATA -0.59,-0.66
DATA -0.60,-0.66
DATA -0.80,0.39
DATA -0.62,-0.45
DATA -0.58,-0.65
DATA -0.71,-0.52
DATA -0.73,-0.22
DATA -0.78,-0.20
DATA 0.29,-0.49
for i=1 to Npatterns
RealOffset = -1.30
ImaginOffset = -0.95
read CRealVal, CImagVal
julia(CRealVal, CImagVal, RealOffset, ImaginOffset)
NEXT i
end

CSUB julia
00000000
27BDFFA8 AFBF0054 AFBE0050 AFB7004C AFB60048 AFB50044 AFB40040 AFB3003C
AFB20038 AFB10034 AFB00030 AFA40058 AFA5005C AFA60060 AFA70064 3C109D00
8E02009C 0040F809 3C044020 00408821 8E02009C 0040F809 3C044080 0040B821
8E02009C 0040F809 3C044000 AFA20018 8E130064 8E030098 8E020080 8C640000
0040F809 00002821 00409021 8E030094 8E020080 8C640000 0040F809 00002821
02402021 0260F809 00402821 00409821 8E120064 8E030094 8E020080 8C640000
0040F809 00002821 02202021 0240F809 00402821 AFA2002C 8E120064 8E020058
02202021 0040F809 02602821 00408821 8E030098 8E020080 8C640000 0040F809
00002821 02202021 0240F809 00402821 AFA20028 8E020094 8C420000 10400085
3C119D00 AFA00020 241EFFFF 8E32005C 8E300058 8E220080 8FA40020 0040F809
00042FC3 00402021 0200F809 8FA5002C 00402021 8FA20060 0240F809 8C450000
AFA20024 8E220098 8C420000 10400069 8FA20020 AFA0001C 8E32005C 8E300058
8E220080 8FA4001C 0040F809 00042FC3 00402021 0200F809 8FA50028 00402021
8FA30064 0240F809 8C650000 00409021 8FB30024 10000025 0000A021 8E350060
8E220058 02602021 0040F809 02602821 00408021 8E220058 02402021 0040F809
02402821 02002021 02A0F809 00402821 00402021 8FA20058 02C0F809 8C450000
0040B021 8E35005C 8E300058 02602021 0200F809 02402821 8FA40018 0200F809
00402821 00402021 8FA3005C 02A0F809 8C650000 26940001 24030051 52830017
8E230048 00409021 02C09821 8E360068 8E35005C 8E220058 02602021 0040F809
02602821 00408021 8E220058 02402021 0040F809 02402821 02002021 02A0F809
00402821 00402021 02C0F809 02E02821 505EFFCA 8E36005C 8E230048 32820002
000221C0 000213C0 00442023 32820004 00022B80 00021580 00451023 00821021
32940001 00142200 0094A023 0054A021 AFB40010 8C620000 8FA40020 8FA5001C
00803021 0040F809 00A03821 8FA2001C 24420001 AFA2001C 8E220098 8C420000
8FA3001C 0062102B 5440FF9C 8E32005C 8FA20020 24420001 AFA20020 8E220094
8C420000 8FA30020 0062102B 5440FF80 8E32005C 8FBF0054 8FBE0050 8FB7004C
8FB60048 8FB50044 8FB40040 8FB3003C 8FB20038 8FB10034 8FB00030 03E00008
27BD0058
End CSUB

[/code]

The C code is attached so you can see how easy it was to do the port, just a question of converting the operators to function calls:

[code]
void julia(float *CRealVal, float *CImagVal, float *RealOffset, float *ImaginOffset){
long MAXIT=80,COUNT,X,Y;
float XDelta, YDelta, CX, CY, Zr, Zi, new_Zr, new_Zi, GAP;
float SIZE=LoadFloat(0x40200000), four=LoadFloat(0x40800000), two=LoadFloat(0x40000000);
GAP=FDiv(IntToFloat(VRes),IntToFloat(HRes));
XDelta=FDiv(SIZE,IntToFloat(HRes));
YDelta=FDiv(FMul(SIZE, GAP),IntToFloat(VRes));
for(X=0;X<HRes;X++){
CX=FAdd(FMul(IntToFloat(X),XDelta),*RealOffset);
for(Y=0;Y<VRes;Y++){
CY=FAdd(FMul(IntToFloat(Y),YDelta),*ImaginOffset);
Zr=CX;
Zi=CY;
COUNT=0;
while((COUNT<=MAXIT) && (FCmp(FAdd(FMul(Zr,Zr),FMul(Zi,Zi)),four)==-1)){
new_Zr=FAdd(FSub(FMul(Zr,Zr),FMul(Zi,Zi)),*CRealVal);
new_Zi=FAdd(FMul(two,FMul(Zr,Zi)),*CImagVal);
Zr=new_Zr;
Zi=new_Zi;
COUNT++;
}
DrawPixel(X,Y,(COUNT & 4)*4177920 + (COUNT & 2)*32640 + (COUNT & 1)*255);
}
}
}
[/code]

Edited by matherp 2015-10-22
 
isochronic
Guru

Joined: 21/01/2012
Location: Australia
Posts: 689
Posted: 01:43am 21 Oct 2015
Copy link to clipboard 
Print this post


I ( a distant observer ) gather that something like

CY = Y * YDelta + ImaginOffset


is

CY=FAdd(FMul(IntToFloat(Y),YDelta),*ImaginOffset);
?

Are the FAdd, FMul etc part of the CX32 libraries ?
Juicy !!



 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9610
Posted: 01:51am 21 Oct 2015
Copy link to clipboard 
Print this post

...bow down to matherp - the Cfunction God...
Smoke makes things work. When the smoke gets out, it stops!
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 01:54am 21 Oct 2015
Copy link to clipboard 
Print this post

  Quote  Are the FAdd, FMul etc part of the CX32 libraries ?


No, these are functions that Geoff has included in the MM firmware that can be called from CFunctions. They get round the fact that the XC32 compiler doesn't generate properly position independent code. All these helper functions are defined in cfunctions.h which Geoff distributes with the Micromite firmware.

Here is CSUB Mandelbrot: 20 seconds on a MM+/ILI9341

[code]
OPTION EXPLICIT
OPTION DEFAULT NONE
DIM FLOAT RealOffset = -2.0 ,ImaginOffset = -0.95, size=2.8
timer=0
mandelbrot(size, RealOffset, ImaginOffset)
print timer
end
CSUB mandelbrot
00000000
27BDFFA8 AFBF0054 AFBE0050 AFB7004C AFB60048 AFB50044 AFB40040 AFB3003C
AFB20038 AFB10034 AFB00030 00808821 AFA5005C AFA60060 3C109D00 8E02009C
0040F809 3C044080 0040F021 8E02009C 0040F809 3C044000 AFA2001C 8E130064
8E030098 8E020080 8C640000 0040F809 00002821 00409021 8E030094 8E020080
8C640000 0040F809 00002821 02402021 0260F809 00402821 0040A021 8E130064
8E320000 8E030094 8E020080 8C640000 0040F809 00002821 02402021 0260F809
00402821 AFA2002C 8E120064 8E020058 8E240000 0040F809 02802821 00408821
8E030098 8E020080 8C640000 0040F809 00002821 02202021 0240F809 00402821
AFA20028 8E020094 8C420000 1040008A 3C119D00 AFA00024 8E32005C 8E300058
8E220080 8FA40024 0040F809 00042FC3 00402021 0200F809 8FA5002C 00402021
8FA2005C 0240F809 8C450000 AFA20018 8E220098 8C420000 1040006F 8FA20024
AFA00020 8E32005C 8E300058 8E220080 8FA40020 0040F809 00042FC3 00402021
0200F809 8FA50028 00402021 8FA30060 0240F809 8C650000 0040B821 8E22009C
0040F809 00002021 00409021 8E22009C 0040F809 00002021 00409821 10000023
0000A021 8E350060 8E220058 02402021 0040F809 02402821 00408021 8E220058
02602021 0040F809 02602821 02002021 02A0F809 00402821 00402021 02C0F809
8FA50018 0040B021 8E35005C 8E300058 02402021 0200F809 02602821 8FA4001C
0200F809 00402821 00402021 02A0F809 02E02821 26940001 24030047 52830018
8E230048 00409821 02C09021 8E360068 8E35005C 8E220058 02402021 0040F809
02402821 00408021 8E220058 02602021 0040F809 02602821 02002021 02A0F809
00402821 00402021 02C0F809 03C02821 2403FFFF 5043FFCB 8E36005C 8E230048
32820002 000221C0 000213C0 00442023 32820004 00022B80 00021580 00451023
00821021 32940001 00142200 0094A023 0054A021 AFB40010 8C620000 8FA40024
8FA50020 00803021 0040F809 00A03821 8FA20020 24420001 AFA20020 8E220098
8C420000 8FA30020 0062102B 5440FF96 8E32005C 8FA20024 24420001 AFA20024
8E220094 8C420000 8FA30024 0062102B 5440FF7A 8E32005C 8FBF0054 8FBE0050
8FB7004C 8FB60048 8FB50044 8FB40040 8FB3003C 8FB20038 8FB10034 8FB00030
03E00008 27BD0058
End CSUB
[/code]
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1593
Posted: 02:34am 21 Oct 2015
Copy link to clipboard 
Print this post

Thanks peter!

I like it!

This are the times (in ms) for Julia on a MM2@48Mhz:
23006
33838
37001
30370
11832
11428
10773
31263
12742
10660
32165
16738
35920

For my old MMbasic 4.7b32 i had to convert the CSub to a CFunction.
ed: but it is actually sufficient to rename CSUB to CFunction.

edit:
Mandelbrot takes 31432ms on a MM2@48Mhz (BP170 w. 240x320LCD)

Regards
MichaelEdited by twofingers 2015-10-22
causality ≠ correlation ≠ coincidence
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1593
Posted: 05:23am 21 Oct 2015
Copy link to clipboard 
Print this post

  WhiteWizzard said  I'm guessing things are 'tokenised' in MMBasic, but will raise the question anyway: will using single-letter variable names result in a faster running program??

Interesting question!
As expected: Size matters (the smaller, the faster)!

MMBasic 4.7B32 MM2@48Mhz

' for declared integers
Dim integer i, This, This_is_a_very_very_long_name

Timer=0
For i = 1 To 1000000
Next i
Print Timer
End


Timer=0
For This = 1 To 1000000
Next This
Print Timer


Timer=0
For This_is_a_very_very_long_name = 1 To 1000000
Next This_is_a_very_very_long_name
Print Timer
end
'Results with dim integer
'1: 21243ms
'2: 27156ms
'3: 75555ms

Timer=0
Do
i=i+1
Loop While i<1000000
Print Timer
End

''Result for "DO.LOOP": 89624ms



' for declared integers
Dim integer i, This, This_is_a_very_very_long_name

Timer=0
For i = 1 To 1000000:Next i
Print Timer
End


Timer=0
For This = 1 To 1000000:Next This
Print Timer


Timer=0
For This_is_a_very_very_long_name = 1 To 1000000:Next This_is_a_very_very_long_name
Print Timer
end
'Results
'with dim integer and one line (For i = 1 To 1000000:Next i)
'1: 21096ms
'2: 27009ms
'3: 75407ms


' for floats (ie without "DIM")
Dim float i, This, This_is_a_very_very_long_name

Timer=0
For i = 1 To 1000000
Next i
Print Timer
End


Timer=0
For This = 1 To 1000000
Next This
Print Timer


Timer=0
For This_is_a_very_very_long_name = 1 To 1000000
Next This_is_a_very_very_long_name
Print Timer
end

'Results
'1: 23633ms
'2: 29547ms
'3: 77944ms


' with dim integer and one line (For i = 1 To 1000000:Next)
'NEXT without var_name

Dim integer i, This, This_is_a_very_very_long_name

Timer=0
For i = 1 To 1000000:Next
Print Timer
End
'Result: 14511ms


The fastest is the "for:next" with short var_name and without the "next var".
The slowest is the "do:loop"

Regards
MichaelEdited by twofingers 2015-10-22
causality ≠ correlation ≠ coincidence
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2944
Posted: 08:52am 21 Oct 2015
Copy link to clipboard 
Print this post

@twofingers - Great little experiments you conducted there!

I am shocked at the time difference between:

Timer=0
For i = 1 To 1000000:Next i
Print Timer
End
(21.096s)

and:

Timer=0
For i = 1 To 1000000:Next
Print Timer
End
(14.511s)

Thats 6.5s saving by not declaring the variable name in the NEXT statement!!




 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1593
Posted: 09:03am 21 Oct 2015
Copy link to clipboard 
Print this post

  WhiteWizzard said   Thats 6.5s saving by not declaring the variable name in the NEXT statement!!

Yes, but I think it is somehow brutal (kind of illegal?). Sometimes make it the difference between doable and not feasible.
causality ≠ correlation ≠ coincidence
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 10:50am 21 Oct 2015
Copy link to clipboard 
Print this post

A few more speed observations for the plain 'basic' version.
With my MM+ and 7inch display, the Julia set took 1979 seconds.

Change
CY = Y * YDelta + ImaginOffset
Zr = CX
Zi = CY

to
Zi = Y * YDelta + ImaginOffset
Zr = CX

and
new_Zr = Zr * Zr - Zi * Zi + CRealVal
new_Zi = 2 * Zr * Zi + CImagVal
Zr = new_Zr
Zi = new_Zi

to
new_Zr = Zr * Zr - Zi * Zi + CRealVal
Zi = 2 * Zr * Zi + CImagVal
Zr = new_Zr

By eliminating two lines of unnecessary assignments, the time reduced to 1791 seconds.

It makes the code less readable but with a significant speed improvement.

I am 20 minutes into another test run which is looking promising.

Jim

VK7JH
MMedit
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 06:02pm 21 Oct 2015
Copy link to clipboard 
Print this post

Last play. Changed the DO... LOOP to FOR... NEXT

FOR X = 0 TO (MM.HRES-1)
CX = X * Xdelta + RealOffset
FOR Y = 0 TO (MM.VRES-1)
Zi = Y * YDelta + ImaginOffset
Zr = CX
'Begin Iteration loop
FOR COUNT = 0 TO MAXIT
IF ( Zr * Zr + Zi * Zi ) >= 4 THEN EXIT FOR
new_Zr = Zr * Zr - Zi * Zi + CRealVal
Zi = 2 * Zr * Zi + CImagVal
Zr = new_Zr
NEXT COUNT
PIXEL X, Y, (COUNT AND 4) * 4177920 + (COUNT AND 2) * 32640 + (COUNT AND 1) * 255)
NEXT Y
NEXT X

Time down to 1616 seconds

Jim
VK7JH
MMedit
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1132
Posted: 08:12pm 21 Oct 2015
Copy link to clipboard 
Print this post

Nice, Jim.
On my MM+ with 320x240 ILI9341 screen, your last version takes 286 seconds.

By knocking the variable names off the NEXT statements, it drops to 277.5 seconds.
Visit Vegipete's *Mite Library for cool programs.
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2944
Posted: 08:19pm 21 Oct 2015
Copy link to clipboard 
Print this post

@TasseyJim,

Out of interest, what CPU are you set to?

Also, as two fingers tests showed a reduction without the NEXT variable name, have you tried this (note vegipete saw a reduction in his post just now)

Should get one last slight improvement

WW
 
     Page 1 of 3    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025