discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

making hexagonal holes into a polyhedron.....

JB
Jordan Brown
Tue, Dec 19, 2023 5:47 PM

Doing something automatic is difficult:  not only would you have to
cache all of the parameters to match against, but you'd also have to
cache all of the $ variables (or at least all of the ones that it
references) and you'd have to detect whether it uses any functions that
can return different values on subsequent calls - currently only
rands(), but in the future may be others.  And since you don't know
which modules might be good to cache, you have to do that on all module
calls, possibly wiping out the advantages.

Having an explicit marking could work.

PR#4478 has an explicit mechanism:  you can put a geometric object into
a variable and then reuse it as many times as you like.  But it's a
pretty significant set of changes and so is slow going.

Doing something automatic is difficult:  not only would you have to cache all of the parameters to match against, but you'd also have to cache all of the $ variables (or at least all of the ones that it references) and you'd have to detect whether it uses any functions that can return different values on subsequent calls - currently only rands(), but in the future may be others.  And since you don't know which modules might be good to cache, you have to do that on all module calls, possibly wiping out the advantages. Having an explicit marking could work. PR#4478 has an explicit mechanism:  you can put a geometric object into a variable and then reuse it as many times as you like.  But it's a pretty significant set of changes and so is slow going.
P
pca006132
Tue, Dec 19, 2023 6:36 PM

There are two things here: whether something is safe to cache, and whether
something is worth it to cache.

The first question is can be solved by some sort of dataflow analysis on
the program, this may be hard to implement on existing codebase though.

The second question is more subtle and much harder in general. Usually,
execution time provides some hint on the cost of a function, but lazy
evaluation from manifold makes this much harder to deal with. Estimating
the number of triangles should be a good estimation for the cost. The
triangle count is an estimate because you don't want to query this, query
will force manifold to evaluate the underlying csg graph and is in general
less efficient comparing to the lazy approach.

  • John
There are two things here: whether something is safe to cache, and whether something is worth it to cache. The first question is can be solved by some sort of dataflow analysis on the program, this may be hard to implement on existing codebase though. The second question is more subtle and much harder in general. Usually, execution time provides some hint on the cost of a function, but lazy evaluation from manifold makes this much harder to deal with. Estimating the number of triangles should be a good estimation for the cost. The triangle count is an estimate because you don't want to query this, query will force manifold to evaluate the underlying csg graph and is in general less efficient comparing to the lazy approach. - John
JB
Jordan Brown
Wed, Dec 20, 2023 3:15 AM

On 12/19/2023 10:36 AM, pca006132 via Discuss wrote:

The second question [whether it's worth caching] is more subtle and
much harder in general. Usually, execution time provides some hint on
the cost of a function, but lazy evaluation from manifold makes this
much harder to deal with. Estimating the number of triangles should be
a good estimation for the cost. The triangle count is an estimate
because you don't want to query this, query will force manifold to
evaluate the underlying csg graph and is in general less efficient
comparing to the lazy approach.

I think that here we are considering only execution-time operations, not
render-time operations.  We already cache render-time results - that is,
the results of rendering a particular CSG subtree.  (But I don't know
the details.)

One thing that we might consider doing to speed up execution time is to
parallelize some of it.  Unlike conventional languages, we mostly don't
have any ordering guarantees.  In particular, we could parallelize all
module invocations.  (Handwaving here on how to arrange that rands()
with a constant seed produces repeatable results.  Also, people might be
unhappy when their echoes happen "out of order".)

But for the particular case that Steve asked about, PR#4478 provides a
decent answer in being able to capture the geometric object resulting
from a module execution and reuse it multiple times without reexecuting
the module.

On 12/19/2023 10:36 AM, pca006132 via Discuss wrote: > The second question [whether it's worth caching] is more subtle and > much harder in general. Usually, execution time provides some hint on > the cost of a function, but lazy evaluation from manifold makes this > much harder to deal with. Estimating the number of triangles should be > a good estimation for the cost. The triangle count is an estimate > because you don't want to query this, query will force manifold to > evaluate the underlying csg graph and is in general less efficient > comparing to the lazy approach. I think that here we are considering only execution-time operations, not render-time operations.  We already cache render-time results - that is, the results of rendering a particular CSG subtree.  (But I don't know the details.) One thing that we might consider doing to speed up execution time is to parallelize some of it.  Unlike conventional languages, we mostly don't have any ordering guarantees.  In particular, we could parallelize all module invocations.  (Handwaving here on how to arrange that rands() with a constant seed produces repeatable results.  Also, people might be unhappy when their echoes happen "out of order".) But for the particular case that Steve asked about, PR#4478 provides a decent answer in being able to capture the geometric object resulting from a module execution and reuse it multiple times without reexecuting the module.