Why is for so slow?

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

Why is for so slow?

adrian
Below is an example of when I use a for loop, the preview is SUPER SLOW compared to when I do the same thing manually.

module part(useFor)
{
  scale(1)
  rotate([0,180,0])
  {
    difference()
    {
      union()
      {
      translate([-d*2,0,0])
        sphere(r=d*2);
      translate([d*2,0,0])
        sphere(r=d*2);
      }

      if (useFor)
      {
        for(i=[0:3])
        {
          letters(i, 0.2, 0.5);
        }
      }
      else
      {
        union()
        {
          d=0.5;
          o=0.2;
          rotate([90,0,0])
          translate([-9/2-.4,-2,1.5])
          linear_extrude(height=1+d)
          offset(delta=o)
          text("A", size=5);

          rotate([103,0,0])
          translate([-2,-7,2])
          linear_extrude(height=1+d)
          offset(delta=o)
          text("B", size=5);

          rotate([90,0,180])
          translate([-9/2-.4,-2,1.5])
          linear_extrude(height=1+d)
          offset(delta=o)
          text("C", size=5);

          rotate([103,0,180])
          translate([-2,-7,2])
          linear_extrude(height=1+d)
          offset(delta=o)
          text("D", size=5);
        }
        translate([0,0,2])
        rotate([0,90,0])
        translate([0,0,-20/2])
        cylinder(r=1,h=20,$fn=20);
      }
    }
  }
}

function RTTs(i) = [
  [[ 87,0,0],   [-9/2-.4, -2, 1.5], "A"],
  [[103,0,0],   [-2,      -7, 2  ], "B" ],
  [[ 87,0,180], [-9/2-.4, -2, 1.5], "C"],
  [[103,0,180], [-2,      -7, 2  ], "D" ]
][i];

module letters(i,o,d=0)
{
  scale(1)
  intersection()
  {
  heart();
    rotate(RTTs(i)[0])
    translate(RTTs(i)[1]+[0,0,-d])
    linear_extrude(height=1+d)
    offset(delta=o)
    text(RTTs(i)[2], size=5);
  }
}

part(useFor=true);

Set useFor to true and rotating around the object is disgustingly slow compared to if useFor=false.  This is just an example. It gets worse when I add more spheres to this in the union.  Funny thing is, the letters can be totally engulfed in the spheres so that they don't show up, and it is still slow.  Something going wrong with the caching?  What's going on?

Using OpenSCAD version 2015.01.23 (git 5a0c4b0).


A
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

adrian
Oops, set d=5 at the beginning.


A
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

adrian
Oh and get rid of the heart() call in letters().


A
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

MichaelAtOz
Administrator
a. If this was just the first time, it needs to build the font cache. As it seems you have tried a few things I assume that is not the cause.

b. for me, on the same version, it is fine. (W7/64bit)

c. "the letters can be totally engulfed in the spheres so that they don't show up, and it is still slow." even tho they are engulfed, they still need calculating to know they are engulfed. But as it is not slow for me...

d. What H/W and S/W platform? (check your graphics drivers are up to date).



Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

Bananapeel
In reply to this post by adrian
I can't reproduce the problem here (Windows x64 2014.12.04). Both versions are fast.
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

adrian
In reply to this post by MichaelAtOz
My SW (OS) is Win7.  My hardware is an older (3-4 yo) Dell Inspiron N411Z laptop with 8GB RAM, 1TB 5400RPM HD, i4-2450M CPU @ 2.5GHz with built in Intel HD Graphics Family video.

I'll see if I can get any driver updates, but the fact that it is slower on my machine indicates a significant run time path divergence.

Turns out the slowdown is caused by the interaction of the for loop with the intersection() of the heart() in letters().  Without the intersection(), the problem isn't seen.  See the following (this is a be complete sample):

d=5;

module heart()
{
  scale([1,.5,1])
  {
      translate([-d*3/4,0,0])
      sphere(r=d, $fn=30);
      translate([d*3/4,0,0])
      sphere(r=d, $fn=30);
      *translate([0,0,d*3/4])
      sphere(r=d, $fn=30);
      translate([0,0,-d*3/4])
      sphere(r=d, $fn=30);
  }
}

module torus(majorR, minorR)
{
  rotate_extrude(convexity = 10, $fn=50)
  translate([majorR,0,0])
  circle(r=minorR, $fn=30);
}

module part(useFor)
{
  scale(1)
  //rotate([0,180,0])
  {
    difference()
    {
      d=0.4;
      o=0.2;
      heart();

      if (useFor)
      {
        for(i=[0:3])
        {
          letters(i, o=o, d=d);
        }
        translate([0,0,21])
        rotate([90,0,0])
        torus(19, .8);
      }
      else
      {
        union()
        {

          rotate(RTTs(0)[0])
          translate(RTTs(0)[1]+[0,0,-d])
          linear_extrude(height=1+d)
          offset(delta=o)
          text(RTTs(0)[2], size=5);

          rotate(RTTs(1)[0])
          translate(RTTs(1)[1]+[0,0,-d])
          linear_extrude(height=1+d)
          offset(delta=o)
          text(RTTs(1)[2], size=5);

          rotate(RTTs(2)[0])
          translate(RTTs(2)[1]+[0,0,-d])
          linear_extrude(height=1+d)
          offset(delta=o)
          text(RTTs(2)[2], size=5);

          rotate(RTTs(3)[0])
          translate(RTTs(3)[1]+[0,0,-d])
          linear_extrude(height=1+d)
          offset(delta=o)
          text(RTTs(3)[2], size=5);

        }
        translate([0,0,21])
        rotate([90,0,0])
        torus(19, .8);

        *translate([0,0,2])
        rotate([0,90,0])
        translate([0,0,-20/2])
        cylinder(r=1,h=20,$fn=20);
      }
    }
*    for(i=[0:3])
      letters(i, 0);
  }
}

function RTTs(i) = [
  [[ 87,0,0],   [-9/2-.4, -2, 1.5], "AA"],
  [[103,0,0],   [-2,      -7, 2  ], "B" ],
  [[ 87,0,180], [-9/2-.4, -2, 1.5], "CC"],
  [[103,0,180], [-2,      -7, 2  ], "D" ]
][i];

module letters(i,o,d=0)
{
  scale(1)
  intersection()
  {
    heart();
    
    rotate(RTTs(i)[0])
    translate(RTTs(i)[1]+[0,0,-d])
    linear_extrude(height=1+d)
    offset(delta=o)
    text(RTTs(i)[2], size=5);
  }
}

part(useFor=0);
Now you should see some slowdown.  I removed a sphere in the heart() module because the programme almost died (even comes close with 3 spheres).


A
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

Bananapeel
Yes, I see the slowdown now. But in all honesty, the way you're doing debugging is wrong. You're not creating the shortest code to show the problem, and testing the role of the for loop incorrectly.

Thank about it: to test if the for loop is the problem, you should expand it manually and see if you get a difference. for (i=[0:3]) { module(i); } should be expanded to union() { module(0); module(1); module(2); module(3); } to test if the for loop is the problem.

You put completely different code inside the for loop and the else (useFor=0) branch. Of course the timing is going to be different. It's executing different code. It has nothing to do with the for loop.

This code should test the for loop, and show that using a loop vs. writing the code manually has no impact on speed (both are slow):
d=5;

module heart()
{
  scale([1,.5,1])
  {
      translate([-d*3/4,0,0])
      sphere(r=d, $fn=30);
      translate([d*3/4,0,0])
      sphere(r=d, $fn=30);
      *translate([0,0,d*3/4])
      sphere(r=d, $fn=30);
      translate([0,0,-d*3/4])
      sphere(r=d, $fn=30);
  }
}

module torus(majorR, minorR)
{
  rotate_extrude(convexity = 10, $fn=50)
  translate([majorR,0,0])
  circle(r=minorR, $fn=30);
}

module part(useFor)
{
  scale(1)
  //rotate([0,180,0])
  {
    difference()
    {
      d=0.4;
      o=0.2;
      heart();

      if (useFor)
      {
        for(i=[0:3])
        {
          letters(i, o=o, d=d);
        }
        translate([0,0,21])
        rotate([90,0,0])
        torus(19, .8);
      }
      else
      {
        union()
        {

          letters(0, o=o, d=d);
          letters(1, o=o, d=d);
          letters(2, o=o, d=d);
          letters(3, o=o, d=d);

        }
        translate([0,0,21])
        rotate([90,0,0])
        torus(19, .8);
      }
    }
*    for(i=[0:3])
      letters(i, 0);
  }
}

function RTTs(i) = [
  [[ 87,0,0],   [-9/2-.4, -2, 1.5], "AA"],
  [[103,0,0],   [-2,      -7, 2  ], "B" ],
  [[ 87,0,180], [-9/2-.4, -2, 1.5], "CC"],
  [[103,0,180], [-2,      -7, 2  ], "D" ]
][i];

module letters(i,o,d=0)
{
  scale(1)
  intersection()
  {
    heart();
   
    rotate(RTTs(i)[0])
    translate(RTTs(i)[1]+[0,0,-d])
    linear_extrude(height=1+d)
    offset(delta=o)
    text(RTTs(i)[2], size=5);
  }
}

part(useFor=0);

Have a nice day,
Bananapeel :)
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

adrian
Right, so its the intersection() that's the problem.  The "loop" had more intersection() operations then the non-loop, causing a slow down.

Thanks,


A
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

adrian
In reply to this post by Bananapeel
Still, after generating the code, I would have expected that the data vertices and faces would have been cached and not have to  redo them every time the POV changes.


A
tp3
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

tp3
On 02/06/2015 03:29 PM, adrian wrote:
> Still, after generating the code, I would have expected that the data
> vertices and faces would have been cached and not have to  redo them every
> time the POV changes.
>
If that would be the case, that would rate as serious issue. As it does
not seem that extreme for others, it's probably "just" the actual
drawing.

Basically https://github.com/openscad/openscad/wiki/Project%3A-Improve-OpenGL-rendering

ciao,
   Torsten.



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

Bananapeel
In reply to this post by adrian
adrian wrote
Still, after generating the code, I would have expected that the data vertices and faces would have been cached and not have to  redo them every time the POV changes.
A
F5 does not generate a polygon, for that you need F6 - which gives much better performance when it's done.

F5 uses some trickery to display the shapes without calculating much beforehand.


Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

kintel
Administrator
In reply to this post by adrian
The reason it’s slow is due to how preview works.

This is hard to explain, but in essence, having intersections as the negative objects in difference is expensive.
The preview rendering algorithm only allows having primitive objects as negatives, and everything else has to be unpacked.
For example:
  A - B*C - D*E
becomes:
  A-B-D + A-B-E + A-C-D + A-C-E

..and if A is more complex:
  A+B - C*D - E*F
becomes:
  A-C-E + A-C-F + A-D-E + A-D-F + B-C-E + B-C-F + B-D-E + B-D-F

As you can see, all combinations has to be rendered, which can take some time, especially on older GPUs, and especially on low-end Intel GPUs.
As Torsten hinted at, we could optimize rendering a lot, but it could be better to optimize the design.

In your particular case, you’re essentially doing this:

(A+B+C) - (A+B+C)*X - (A+B+C)*Y - (A+B+C)*Z - (A+B+C)*W
..where A,B and C are spheres and X, Y, Z, W are extruded letters
(ignoring the torus for simplicity)

I’ll make a mental leap and say that this is equivalent to
(A+B+C) - X - Y -Z -W

i.e., your intersections are not necessary.
Try that and you’ll see a substantial speedup

 -Marius


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

runsun
This post was updated on .
In reply to this post by adrian
Just for reference, this code runs preview very fast the very first time or after cash flush (less than 1 sec) on my Toshiba Satellite (probably 8 yr old) with AMD 64 Athlonx2 + 2GB RAM

Software: Linux Mint 17 MATE 64bit + OpenSCAD 2015.02.01.nightly
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

kintel
Administrator

On Feb 6, 2015, at 15:13 PM, runsun <[hidden email]> wrote:

> Just for reference, this code (preview) runs very fast the very first time or
> after cash flush (less than 1 sec) on my Toshiba Satellite (probably 8 yr
> old) with AMD 64 Athlonx2 + 2GB RAM
>
You probably didn’t set useFor=1

 -Marius


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

runsun
Indeed. Setting it to 1 slows it down (~3sec), and after the preview the computer becomes sticky (unable to pan or zoom), followed by crash of openscad. :(
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

kintel
Administrator
On Feb 6, 2015, at 16:51 PM, runsun <[hidden email]> wrote:

> Indeed. Setting it to 1 slows it down (~3sec), and after the preview the
> computer becomes sticky (unable to pan or zoom), followed by crash of
> openscad. :(
>
I think the crash has been fixed. Did you try a recent dev snapshot?

 -Marius


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

adrian
In reply to this post by kintel
Sorry Marius, what do the operations mean? I'm not familiar with them.


A
Reply | Threaded
Open this post in threaded view
|

Re: Why is for so slow?

kintel
Administrator
On Feb 6, 2015, at 20:02 PM, adrian <[hidden email]> wrote:

> Sorry Marius, what do the operations mean? I'm not familiar with them.
>
It was just meant as an illustration
In my notation:
A+B = union() { A(); B(); }
A-B = difference() { A();  B(); }
A*B = intersection() { A(); B(); }

 -Marius


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org