|
M Benesi
|
 |
« Reply #45 on: October 18, 2015, 02:18:03 AM » |
|
Hi, I mean the math, but in terms which make it easy for me to translate it into MB3D's environment (in order to avoid errors while translating it). Not sure, how it is currently done, but I was hoping there is something between the pure math and the compiled/optimized ASM-stuff.
Hey Andreas, The math for formula 1 and 2 is in the first post of this thread. The math for the "Pine Tree" version of the Mandelbulb is described in post 8. If you want further explanations, ask away. Something I forgot to tell Luca before he started coding: Only add in the x pixel component after the Pine Tree Mandelbulb portion for maximum symmetry. I'd do all 3 (pine tree, mod 1, and mod 2) formulas stand alone, so they can be alternated with one another.
|
|
|
|
|
Logged
|
|
|
|
thargor6
Fractal Molossus
 
Posts: 789
|
 |
« Reply #46 on: October 19, 2015, 12:15:24 AM » |
|
Hi, I think I succeeded with including Formula 1 in my experimental MB3D-solution (i. e., I entered just the text, but in Pascal-syntax). I have combined a classic mandelbulb (i. e. IntPower) with this formula and got the following cool result:  The solution is not really usable now (one cant even save params), but I think it is the way to go. Best regards, Andreas
|
|
|
|
|
Logged
|
|
|
|
|
M Benesi
|
 |
« Reply #47 on: October 19, 2015, 01:18:10 AM » |
|
Looks like the tree I was trimming a few minutes ago. 
|
|
|
|
|
Logged
|
|
|
|
|
M Benesi
|
 |
« Reply #48 on: October 22, 2015, 05:29:39 AM » |
|
So, I split the formulas into the transforms, and the pine tree portions. Made a pine tree with only the x-pixel component as well. I've yet to figure out how to do something like: T1, PTx, T1, PTx, T1, PTxyz, PTx, T2, PTx, T1 T1: transform 1 T2: ... Ahhnolldd ... PTx: Pine tree with x-pixel component only PTxyz: pine tree with x,y, and z pixel components Here is a mix of T1 and PTx...  All the code for the split formulas... with them attached below. Also code for pine tree 1, with no y and z, and pine tree 2 with no y and z... maybe next post. Can't attach any more....  [OPTIONS] .Version = 2 .DEscale = 1 .SIpower = 2 .Double Scale = 2.0 .Double xOff = 2.0 [CONSTANTS] Double = 0.816496580927726 Double = 0.5773502691896258 Double = 0.7071067811865475 [CODE] 558BEC81EC300000005356578B75088B7E308BD8D9D0DD03DC0FDD01DC4F08D9 E0DEC1DC4F10DD5DF8DD03DC4F08DD01DC0FDEC1D9E190DD45F8DD02DC4F10D9 E0DEC1D9E190DD45F8DD02DC4F10DEC1D9E190DD1ADD1BDD1990DD03DC02DC4F 10DD5DF890DD03D9E0DC02DC4F1090DD45F8DC0FDD01DC4F08DEC190DD45F8DC 4F08D9E0DD01DC0FDEC190DD19DD1BDD1A90DD03DC4FF0DC67E8DD1BDD02DC4F F0DD1ADD01DC4FF0DD1990D9D08BC35F5E5B89EC5DC20800 [END]
Description:
Cool?? :D absolute value xyz transform;
// STEP1: "Benesi transform 1" tx=(x*sqrt(2/3)-z*sqrt(1/3))*sqrt(1/2); z=abs(x*sqrt(1/3) + z*sqrt(2/3)); x=abs(tx-y*sqrt(1/2)); y=abs(tx+y*sqrt(1/2)); tx=x*sqrt(1/2)+y*sqrt(1/2); y=-x*sqrt(1/2)+y*sqrt(1/2); x=tx*sqrt(2/3)+z*sqrt(1/3); z=-tx*sqrt(1/3)+z*sqrt(2/3);
x=scale*x-offset; //scale =2 offset=2 y=scale*y; z=scale*z;
................................................................Transform 2...,,,,.,,,,.
[OPTIONS] .Version = 2 .DEscale = 1 .SIpower = 2 .Double Scale = 2.0 .Double xOff = 2.0 [CONSTANTS] Double = 0.816496580927726 Double = 0.5773502691896258 Double = 0.7071067811865475 [CODE] 558BEC81EC300000005356578B75088B7E308BD8D9D0DD03DC0FDD01DC4F08D9 E0DEC1DC4F10DD5DF8DD02DC4F10DD1A90DD03DC4F08DD01DC0FDEC190DD45F8 DC2290DD45F8DC0290D8C8DD5DF0D8C8DD5DF8D8C8DD19D9D0DD45F0DC01D9FA DC67E8D9E1DC4FF0DC4F10DD1B90DD45F8DC01D9FADC67E8D9E1DC4FF0DC4F10 DD1A90DD45F8DC45F0D9FADC67E8D9E1DC4FF0DD1990DD02DC03DD02DC23DD1A DD5DF890DD45F8DC0FDD01DC4F08DEC1DD45F8DC4F08D9E0DD01DC0F90DEC1DD 19DD1B90D9D08BC35F5E5B89EC5DC20800 [END]
Description:
The cool Benesi pinetree formula. Use in conjunction with normal BenesiPine1 or it is messy! Or any other formula :) (Three iters of pine1 + one of pine2)
// STEP1: "Benesi fold 2" tx=(x*sqrt(2/3)-z*sqrt(1/3))*sqrt(1/2); y=y*sqrt(1/2); z=(x*sqrt(1/3) + z*sqrt(2/3))^2; tx=(tx-y)^2; ty=(tx+y)^2;
x=abs(sqrt(ty+z)-offset2)*scale2*sqrt(1/2) ; y=abs(sqrt(tx+z)-offset2)*scale2*sqrt(1/2) ; z=abs(sqrt(tx+ty)-offset2)*scale2 ;
tx=y+x; y=y-x; x=z*sqrt(1/3)+x*sqrt(2/3); z=z*sqrt(2/3)-x*sqrt(1/3);
..................................Pine Tree X pixel Only!@$................................... [OPTIONS] .Version = 2 .DEscale = 1 .SIpower = 2 [CONSTANTS]
[CODE] 558BEC81EC300000005356578B75088B7E308BD8D9D0DD03D8C8DD5DF8DD02D8C8DD5DF0DD01D8C8DD5DE8 DD03D8C0DD45F0DC45E8D9FADEF9DD5DE090DD45F8DC65F0DC65E890DD45E0DD 45F0DC65E8DEC990DD45E0D8C0DC09DC0A90DD1A90DD1990DC46 18DD1BD9D08BC35F5E5B89EC5DC20800 [END]
Description:
//"Benesi pinetree X pixel" xt = x*x; yt = y*y; zt = z*z; t = 2*x/sqrt(yt+zt); x = xt-yt-zt+Cx; z = t*(yt-zt); y = 2*t*y*z;
...................................................Pine Tree with xyz pixel...................... [OPTIONS] .Version = 2 .DEscale = 1 .SIpower = 2 [CONSTANTS]
[CODE] 558BEC81EC300000005356578B75088B7E308BD8D9D0DD03D8C8DD5DF8DD02D8C8DD5DF0DD01D8C8DD5DE8 DD03D8C0DD45F0DC45E8D9FADEF9DD5DE090DD45F8DC65F0DC65E890DD45E0DD 45F0DC65E8DEC990DD45E0D8C0DC09DC0A90DC4620DD1A90DC4628DD1990DC46 18DD1BD9D08BC35F5E5B89EC5DC20800 [END]
Description:
//"Benesi pinetree XYZ pixel" xt = x*x; yt = y*y; zt = z*z; t = 2*x/sqrt(yt+zt); x = xt-yt-zt+Cx; z = t*(yt-zt); y = 2*t*y*z;
[/code][/code][/code][/code]
|
|
|
|
Logged
|
|
|
|
thargor6
Fractal Molossus
 
Posts: 789
|
 |
« Reply #49 on: October 22, 2015, 11:46:18 PM » |
|
Edit, I finally succeeded by translating the first non-trivial formula (your initial formula 1 +2), so that it runs on the experimental embedded formula compiler and leads to the same result. Using this system, this formula can be written like this: [OPTIONS] .Version = 2 .DEscale = 1 .SIpower = 2 [SOURCE] procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D); var scale, offset: Double; sqrt_1_2, sqrt_1_3, sqrt_2_3: Double; start_x, start_y, start_z: Double; temp_x, temp_y, temp_z, temp: Double; new_x, new_y, new_z: Double; x_temp, y_temp, z_temp: Double;
begin scale := 2.0; offset := 2.0;
sqrt_1_2 := sqrt(1.0/2.0); sqrt_1_3 := sqrt(1.0/3.0); sqrt_2_3 := sqrt(2.0/3.0);
start_x := x; start_y := y; start_z := z; temp_x := start_x*sqrt_2_3-start_z*sqrt_1_3; new_z := start_x*sqrt_1_3 + start_z*sqrt_2_3; new_x := temp_x*sqrt_1_2-start_y*sqrt_1_2; new_y := temp_x*sqrt_1_2+start_y*sqrt_1_2;
new_x := abs(new_x); new_y := abs(new_y); new_z := abs(new_z);
temp_x := new_x*sqrt_1_2+new_y*sqrt_1_2; new_y := -new_x*sqrt_1_2+new_y*sqrt_1_2; new_x := temp_x*sqrt_2_3+new_z*sqrt_1_3; new_z := -temp_x*sqrt_1_3+new_z*sqrt_2_3;
start_x:=scale*new_x-offset; //scale =2 offset=2 start_y:=scale*new_y; start_z:=scale*new_z;
x_temp:=start_x*start_x; y_temp:=start_y*start_y; z_temp:=start_z*start_z; temp:=2.0*start_x/sqrt(y_temp+z_temp);
new_x:= x_temp - y_temp - z_temp; new_z:=temp*(y_temp-z_temp); //y and z variables are switched to add symmetry new_y:=temp*2.0*start_y*start_z;
x := new_x + PIteration3D^.J1; y := new_y + PIteration3D^.J2; z := new_z + PIteration3D^.J3;
end; [END]
Description: ...
To compare speed, I rendered the example you provided at 960x720 once with the ASM-formula, once with the on-the-fly compiled formula: Hand-coded ASM: 14 seconds On-the-fly compiled : 42 seconds
|
|
|
|
« Last Edit: October 23, 2015, 12:53:20 AM by thargor6 »
|
Logged
|
|
|
|
|
lycium
|
 |
« Reply #50 on: October 23, 2015, 02:26:48 AM » |
|
Maybe it's failing to optimise those sqrt(1/3) etc. Could try replacing with the result, i.e. 0.57735026918962576450914878050196
|
|
|
|
|
Logged
|
|
|
|
thargor6
Fractal Molossus
 
Posts: 789
|
 |
« Reply #51 on: October 23, 2015, 03:09:11 AM » |
|
Maybe it's failing to optimise those sqrt(1/3) etc. Could try replacing with the result, i.e. 0.57735026918962576450914878050196
You are right, of course, thanks for the heads up! When I use those constants, the render takes 28 seconds (compared to 14 seconds for handcoded ASM), probably there is some more room for improvement. Cheers!
|
|
|
|
|
Logged
|
|
|
|
|
M Benesi
|
 |
« Reply #52 on: October 23, 2015, 04:16:58 AM » |
|
Can we compare the binary (or hex) the compiler generates with the ASM hex/binary? and.. it's a bit off topic, but is there a way to select each formula you want to use for each iteration in M3D? | Iteration | | Formula | | 1 | | Transform 1 | | 2 | | Pine Tree_x only | | 3 | | Transform 1 | | 4 | | Pine Tree | | 5 | | Transform 2 | | n... | | ... |
|
|
|
|
« Last Edit: October 23, 2015, 04:24:09 AM by M Benesi »
|
Logged
|
|
|
|
|
lycium
|
 |
« Reply #53 on: October 23, 2015, 04:59:55 AM » |
|
I find it a bit odd that JIT compiled code is (so much!) slower than the normal static code.
As a point of comparison, Chaotica's new render engine (and all transforms) is written in our functional language Winter, and even doing CPU vs CPU comparisons (there is an OpenCL backend for GPUs) the MSVC compiled code gets spanked by LLVM-backed JIT code. This is largely because many things are known at render-time that are not at compile-time, but also because LLVM makes highly optimised code using the latest CPU extensions (such as AVX2, AVX-512) on CPUs which support it.
|
|
|
|
|
Logged
|
|
|
|
|
M Benesi
|
 |
« Reply #54 on: October 23, 2015, 07:13:55 AM » |
|
Edit, I finally succeeded by translating the first non-trivial formula (your initial formula 1 +2), so that it runs on the experimental embedded formula compiler and leads to the same result.  Ok, after doing Lycium's suggestion with the square roots, some questions. Do you have to assign the variables every iteration? Doesn't using fewer variables for the calculation mean fewer stack (memory) movements? Does the compiler automatically eliminate extra variables? Maybe test the code I make with fewer variables... Commenting/changing your code below. Doing another revision below the following code because I'm not sure about your compiler- whether it's cool to use the x,y, and z variables as part of the iteration. Second code eliminates more variables by using x,y, and z in the iteration. SECOND CODE LOOKS BETTER>>>>... but the compiler might already streamline variables, ehh? So... I don't know. I can't test it. I'd recommend second code if it works. [OPTIONS] .Version = 2 .DEscale = 1 .SIpower = 2 [SOURCE] procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D); var scale, offset: Double; sqrt_1_2, sqrt_1_3, sqrt_2_3: Double; // start_x, start_y, start_z: Double; // eliminate these variables..... // temp_x, temp_y, temp_z, temp: Double; // how about these too??? new_x, new_y, new_z: Double; x_temp, y_temp, z_temp, temp: Double; //gotta add a new temp variable because we took out the others...
begin scale := 2.0; // can you take all these variable assignments, and do them outside of the iteration??? offset := 2.0;
sqrt_1_2 := 0.7071067811865475; sqrt_1_3 := 0.5773502691896258; sqrt_2_3 := 0.816496580927726; // to here...
// start_x := x; start_y := y; start_z := z;
// can you eliminate the start_x, start_y, and start_z variables???
x_temp := x*sqrt_2_3 - z*sqrt_1_3; new_z := x*sqrt_1_3 + z*sqrt_2_3; new_x := x_temp*sqrt_1_2-y*sqrt_1_2; new_y := x_temp*sqrt_1_2+y*sqrt_1_2;
new_x := abs(new_x); new_y := abs(new_y); new_z := abs(new_z);
x_temp := new_x*sqrt_1_2+new_y*sqrt_1_2; new_y := -new_x*sqrt_1_2+new_y*sqrt_1_2; new_x := x_temp*sqrt_2_3+new_z*sqrt_1_3; new_z := -x_temp*sqrt_1_3+new_z*sqrt_2_3;
new_x:=scale*new_x-offset; //scale =2 offset=2 new_y:=scale*new_y; new_z:=scale*new_z;
x_temp:=new_x*new_x; y_temp:=new_y*new_y; z_temp:=new_z*new_z; temp:=2.0*new_x/sqrt(y_temp+z_temp);
new_x:= x_temp - y_temp - z_temp; new_y:=temp*2.0*new_y*new_z; // put this above the next one, so I could eliminate variables.... new_z:=temp*(y_temp-z_temp); //math for y and z variables is switched from regular bulb formula to add symmetry x := new_x + PIteration3D^.J1; // come on... don't add the next pixel components in. come on... :D :p do what ya want. y := new_y; // y := new_y + PIteration3D^.J2; z := new_z; // z := new_z + PIteration3D^.J3;
end; [END]
Description: ...
With x,y, and z used for variables... [OPTIONS] .Version = 2 .DEscale = 1 .SIpower = 2 [SOURCE] procedure BenesiPineTree(var x, y, z, w: Double; PIteration3D: TPIteration3D); var scale, offset: Double; sqrt_1_2, sqrt_1_3, sqrt_2_3: Double; // start_x, start_y, start_z: Double; // eliminate these variables..... // temp_x, temp_y, temp_z, temp: Double; // how about these too??? // new_x, new_y, new_z: Double; // for this one, these get eliminated too.... x_temp, y_temp, z_temp, temp: Double; //gotta add a new temp variable because we took out the others...
begin scale := 2.0; // can you take all these variable assignments, and do them outside of the iteration??? offset := 2.0;
sqrt_1_2 := 0.7071067811865475; sqrt_1_3 := 0.5773502691896258; sqrt_2_3 := 0.816496580927726; // up to here, if you can eliminate these variable assignments.. if it's necessary?
x_temp := x*sqrt_2_3 - z*sqrt_1_3; z := x*sqrt_1_3 + z*sqrt_2_3; x := x_temp*sqrt_1_2-y*sqrt_1_2; y := x_temp*sqrt_1_2+y*sqrt_1_2;
x := abs(x); // can you do this above? I don't know how tight the compiler is y := abs(y); // so if it's moving the stack and registers around before it does these commands z := abs(z); // it might be faster to do the abs() command up above, instead of here
x_temp := x*sqrt_1_2 + y*sqrt_1_2; y := -x*sqrt_1_2 + y*sqrt_1_2; x := x_temp*sqrt_2_3 + z*sqrt_1_3; z := -x_temp*sqrt_1_3 + z*sqrt_2_3;
x:=scale*x-offset; //scale =2 offset=2 y:=scale*y; z:=scale*z;
x_temp:=x*x; y_temp:=y*y; z_temp:=z*z; temp:=2.0*x/sqrt(y_temp+z_temp);
x:= x_temp - y_temp - z_temp + PIteration3D^.J1; // moved the pixel component up here.... y:=temp*2.0*y*z; // I didn't add in the y or z pixel components because... it is more awesome that way... @!@$!@$ z:=temp*(y_temp-z_temp); //math for y and z variables is switched from regular bulb formula to add symmetry // x := new_x + PIteration3D^.J1; // come on... don't add the next pixel components in. come on... :D :p do what ya want. // y := new_y; // y := new_y + PIteration3D^.J2; // z := new_z; // z := new_z + PIteration3D^.J3;
end; [END]
Description: ...
|
|
|
|
|
Logged
|
|
|
|
DarkBeam
Global Moderator
Fractal Senior
     
Posts: 2512
Fragments of the fractal -like the tip of it
|
 |
« Reply #55 on: October 23, 2015, 10:08:01 AM » |
|
My handcoded uses just one temp for the fold and three for the transform. I did other reductions and stuff. By the way. Can you try to enable SSE2? Jesse did many formulas with it and it could help  I can surely predict that ppl will not use slow formulas, as all slow ones I did stay unused.
|
|
|
|
|
Logged
|
No sweat, guardian of wisdom!
|
|
|
|
lycium
|
 |
« Reply #56 on: October 23, 2015, 10:44:13 AM » |
|
Re-using variables is very bad for code readability/clarity, and doesn't result in fewer registers being used or anything like that. Having to declare variables ahead of time is awful to read and to write, and gets in the way of making variables as locally scoped as possible and declared constant. Compilers make short work of functions which don't modify any global state and just do a bunch of arithmetic on const variables. Const const const const 
|
|
|
|
|
Logged
|
|
|
|
DarkBeam
Global Moderator
Fractal Senior
     
Posts: 2512
Fragments of the fractal -like the tip of it
|
 |
« Reply #57 on: October 23, 2015, 12:17:58 PM » |
|
An assembly formula is never readable nor reusable 
|
|
|
|
|
Logged
|
No sweat, guardian of wisdom!
|
|
|
thargor6
Fractal Molossus
 
Posts: 789
|
 |
« Reply #58 on: October 23, 2015, 12:30:02 PM » |
|
Commenting/changing your code below. Doing another revision below the following code because I'm not sure about your compiler...
Hi, thanks for the comment, but please note, that for me performance at this step of development was not important (except for those obvious things like precalculating constants), the main achievement was to make this formula to work at all... and getting the same result  There was a lot of guessing involved, because there are so many versions of those formulas around and some of them use variables in a cryptic way, making it not clear, if it is a typo or intended (e.g. using tx and xt as temporary variables, and using them both ;-)). So, it was hard to guess, if the formula is wrong or the compiler did not work right (because there where also problems with compiler, e.g. when using code with a const-section it seems to overwrite internal stuff causing crashes or weird results). A test-version will be available soon to people who are interested (no public release at the current state) Best regards
|
|
|
|
|
Logged
|
|
|
|
DarkBeam
Global Moderator
Fractal Senior
     
Posts: 2512
Fragments of the fractal -like the tip of it
|
 |
« Reply #59 on: October 23, 2015, 12:47:42 PM » |
|
|
|
|
|
|
Logged
|
No sweat, guardian of wisdom!
|
|
|
|