![]() |
Forum Index : Microcontroller and PC projects : Fractal Images
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1134 |
I found one _very_ slight improvement. In the lines IF ( Zr * Zr + Zi * Zi ) >= 4 THEN EXIT FOR andZi = 2 * Zr * Zi + CImagVal the numerical constants 4 and 2 can be moved into variables, resulting in a whopping ... get ready ... 1/8 second improvement.Visit Vegipete's *Mite Library for cool programs. |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Now that is really surprising as I would have thought a variable-to-value lookup would take longer than 'passing' the actual value ![]() I say this exercise should become a challenge to see who can get the fastest time (without CFunctions) ![]() WW |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
@WW CPU speed is the default of 100MHz Removing the variable names for the FOR... NEXT loops shaved another 30 seconds off, bring the time down to 1581 seconds. (The initial time to beat was 1979 seconds). I have also tried using Zr^2 instead of Zr*Zr. The power operator was slightly slower as expected but not as much difference as I thought. About 30 seconds slower. Putting multiple statements on the one line made negligible difference. I haven't tried using short variable names and removing blank spaces yet. Putting the loops at the start of the code makes no difference. There were big differences in the days of line numbers but not any more. When passing the lines of code, numbers have to be converted from strings to binary which is why it can be faster to use variables instead of literal numbers. Jim VK7JH MMedit |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Ok - this was my 'benchmark' and was indeed what roughly what I was seeing initially for 'Julia' (actually 289.98 seconds) Have applied all the MMBASIC stream-lining that I can think of and here is the new 'target' to beat: 189.616 seconds. Set on a 64-pin MM+ with 2.4" ILI9341 TFT (320x240) and the very latest Beta ![]() WW Note: Only BASIC used - no CFUNCTIONS in sight! |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Thanks Jim! ![]() This seems to be the optimal code (or?): It takes 402932ms vs 519688ms for Geoffs original version (uM2@48/2.4 LCD 240x320). Michael EDIT: I hope that Geoff interprets this game not as a criticism! ![]() causality ≠ correlation ≠ coincidence |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Hi Michael, I am 'hooked' on this at the moment and am currently down from an initial 289.978 seconds to 184.895. So from just under five minutes, to a fraction over 3 minutes. This is on a 64pin MM+ so is not comparable with your timings; however, try these things to see if it improves your timings: 1> Shorten ALL variable names to just a single character 2> In the PIXEL command, replace the 4177920 and 32640 values with % variables 3> multiline statements 4> In the 'Exit For' line, replace >=4 with >3 5> Instead of adding negative numbers (i.e. CR=-0.78, and then nZr=..Zi+CR), replace with nZr=..Zi-CR All these things shaved off almost two minutes for my 320x240 display! Let us know how you get on ![]() WW |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Hi WW, ![]() I'm now at 363468ms (~70%). Not bad! But the code hurts my eyes! ![]() It's a job for a preprocessor, as Peter (C.) would say, I guess. 'JULIA.BAS - Draws Julia set fractal images
'by loki CPU 48 ' for uM2 Dim As Integer H, C, W, U CLS 'Specify initial values S = -1.30 T = -0.95 '------------------------------------------------* 'Set the Julia set constant [eg C = -1.2 + 0.8i] D = -0.78 E = -0.20 '------------------------------------------------* Q=80 'max iterations GAP = MM.VRes / MM.HRes SIZE = 2.50 P = SIZE / MM.HRes O = (SIZE * GAP) / MM.VRes H=MM.HRes-1 V=MM.VRes-1 W=4177920 U=32640 Timer=0 For X=0 To H:M=X*P+S:For Y=0 To V:J=Y*O+T:R=M For C=0 To Q:If R*R+J*J>3 Then Exit For N=R*R-J*J+D:J=2*R*J+E:R=N Next Pixel X,Y,(C And 4)*W+(C And 2)*U+(C And 1)*255:Next:Next Print Timer EDIT: That takes 363394ms (again -0.02%)! ![]() Regards Michael causality ≠ correlation ≠ coincidence |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
twofingers code took 1358 seconds on my MM+ with 7in display The only change I made was to "If R*R+J*J>3 Then Exit For" I put it back to "If R*R+J*J>=4 Then Exit For" R and J are both floats so >3 is not the same as >=4 Jim VK7JH MMedit |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Are you sure this applies also to the northern hemisphere? I thought, this only applies in the southern hemisphere. (just kidding ![]() The result for the corrected code (uM2@48/2.4, LCD 240x320) is 372780ms. I'm curious if there are some more improvements are possible ... causality ≠ correlation ≠ coincidence |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Maybe (unable to test it) can squeeze a bit more speed by changing [code] For C=0 To Q:If R*R+J*J>=4 Then Exit For N=R*R-J*J+D:J=2*R*J+E:R=N [/code] into [code] For C=0 To Q:If R^2+J^2>=4 Then Exit For N=R^2-J^2+D:J=2*R*J+E:R=N [/code] Microblocks. Build with logic. |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
AFAIK Jim has already tried. Regards Michael EDIT: For X=0 To H:M=X*P+S:For Y=0 To V:J=Y*O+T:R=M
For C=0 To Q:If R^2+J^2>=4 Then Exit For N=R^2-J^2+D:J=2*R*J+E:R=N Next Takes 378374ms. causality ≠ correlation ≠ coincidence |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Ha, i should read the whole thread before doing suggestions. :) Microblocks. Build with logic. |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Ok, i can see one more little optimisation when the calculations made at the start of the Y loop are precalculated. Now these calculations are done for each X. First need to dimension an array to hold the values. [code] DIM K(MM.Vres) [/code] Then fill this array with the right values [code] For Y=0 To V:K(Y)=Y*O+T:NEXT [/code] and change the loop to use the precalculated values [code] For X=0 To H:M=X*P+S:For Y=0 To V:J=K(Y):R=M [/code] That should shave of another 0.1% ![]() ![]() Microblocks. Build with logic. |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Hi MB, nice try, but this is slower than I expected. Takes 379606ms (compared with 372780ms). Thanks your assistance! ![]() Michael causality ≠ correlation ≠ coincidence |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1134 |
Hmm, there seem to be variations based on hardware perhaps. Michael's (TwoFingers) eye hurting code with positive initial values and subtraction instead of addition takes 416188 on my MM+64 with 320x240 ILI9341. (This compares with 363394ms that Michael reports.) Since I haven't got all day, I changed to CPU 100, giving a time of 238858. Out of curiosity, I changed 'R*R+J*J>=4' to 'R*R+J*J>4'. With floating point values, how often would the result be exactly 4.0? Often enough for a 0.1 second INCREASE in time. For my last test, I precomputed the colour values and stored them in an array. The result: 5 seconds faster. Waahhoooo! Time on my system: 233861. (And I did include the colour precomputation in the timing.) 'JULIA.BAS - Draws Julia set fractal images
'by loki CPU 100 ' for uM2 Dim As Integer H, C, W, U dim as integer B(81) CLS 'Specify initial values S = 1.30 T = 0.95 '------------------------------------------------* 'Set the Julia set constant [eg C = -1.2 + 0.8i] D = -0.78 E = -0.20 '------------------------------------------------* Q=80 'max iterations GAP = MM.VRes / MM.HRes SIZE = 2.50 P = SIZE / MM.HRes O = (SIZE * GAP) / MM.VRes H=MM.HRes-1 V=MM.VRes-1 W=4177920 U=32640 Timer=0 for X=1 to 81:B(X)=(X And 4)*W+(X And 2)*U+(X And 1)*255:NEXT For X=0 To H:M=X*P-S:For Y=0 To V:J=Y*O-T:R=M For C=0 To Q:If R*R+J*J>=4 Then Exit For N=R*R-J*J+D:J=2*R*J+E:R=N Next Pixel X,Y,B(C):Next:Next Print Timer Visit Vegipete's *Mite Library for cool programs. |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Out of interest, can you run at CPU120? ![]() |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Also; change (x AND 4) and (x AND 2) to (x AND &b100) and (x AND &b10). This gave me a further reduction! ![]() |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
That did not work for me, sorry. ![]() Vegipetes code takes 369077ms (uM2@48/2.4, LCD 240x320). Very good! ![]() WWs code For X=1 To 81:B(X)=(X And &B100)*W+(X And &B10)*U+(X And 1)*255:Next
takes 369076ms. ![]() and this For C=0 To Q:B(C)=(C And &B100)*W+(C And &B10)*U+(C And 1)*255:Next
For X=0 To H:M=X*P-S:For Y=0 To V:J=Y*O-T:R=M For C=0 To Q:If R*R+J*J>=&B100 Then Exit For N=R*R-J*J+D:J=&B10*R*J+E:R=N Next Pixel X,Y,B(C):Next:Next 369018ms! ~50ms better! ![]() Thanks Pete and WW! Michael causality ≠ correlation ≠ coincidence |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
I haven't posted all my 'hints' yet, but am currently at 184,122 ms as the most optimised time on a MM+ and a 2.4" ILI9341 SPI. However, this is with >3 as opposed to >=4 (which has been pointed out is not technically correct for Floats)! Will be trying in the next 24hrs to correct this . . . |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Amazing: This is faster (366517ms) For C=0 To Q:If R*R+J*J>=4 Then Exit For
N=R*R-J*J+D:J=&B10*R*J+E:R=N NEXT than this (369070ms) For C=0 To Q:If R*R+J*J>=4 Then Exit For
N=R*R-J*J+D:J=2*R*J+E:R=N NEXT or this (369017ms) For C=0 To Q:If R*R+J*J>=&B100 Then Exit For
N=R*R-J*J+D:J=&B10*R*J+E:R=N NEXT or this (371571ms) For C=0 To Q:If R*R+J*J>=&B100 Then Exit For
N=R*R-J*J+D:J=2*R*J+E:R=N but this is even faster (366011ms) For C=0 To Q:B(C)=(C And &H4)*W+(C And &H2)*U+(C And 1)*255:Next
For X=0 To H:M=X*P-S:For Y=0 To V:J=Y*O-T:R=M For C=0 To Q:If R*R+J*J>=&H4 Then Exit For N=R*R-J*J+D:J=&H2*R*J+E:R=N Next Pixel X,Y,B(C):Next:Next Michael causality ≠ correlation ≠ coincidence |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |