YOUR ACCOUNT

Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
Here is a native julia set filter - but the render time is insanely high / freezes, even for a few iterations (3-4 iterations). Me thinks the loop machinery needs oil! smile:?:

Native Julia Set.ffxml
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Did you read the "explosive recursions" warning about multiple outgoing connections from a single component within the loop? If I am not mistaken you have created a recursive loop that calls itself 12 times in each iteration, so at 3 iterations you get 12^3=1728 times recursion of the loop.
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
I might be mistaken, but no coordinate space branching is going on here, i.e. there is no spatial distorter involved (offset, noise distortion etc) and it is the same internal x and y that is used. This should not be a problem, but something is surely eating up performance.
  Details E-Mail
Vladimir Golovin
Administrator
Posts: 3446
Filters: 55
Quote
I might be mistaken, but no coordinate space branching is going on here, i.e. there is no spatial distorter involved (offset, noise distortion etc) and it is the same internal x and y that is used. This should not be a problem, but something is surely eating up performance.


The sample cache, in addition to matching coordinates, requires some extra conditions to be met in order to consider a sample a cache hit (this is a historical artifact), so even if the samples are at the same coordinates, a cache miss may still occur, which would lead to an exponential recursion.
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Per my logic, which may be wrong, ANY branching (regardless of it being coordinate space or not) inside a loop would cause an exponential amount of components and recursion. smile:?:
  Details E-Mail
Vladimir Golovin
Administrator
Posts: 3446
Filters: 55
Not any. The sample cache may work for some combinations of components, and may not work for others. This is fixable, but it will require refactoring and re-testing the get_sample implementation of all FF components, so don't expect a fix quickly.
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
If you increase the iterations in the attached filter to 7 it starts to grind to a halt and this would be due to recursion at the rate of 3^n just because of branching into 3 inside the loop. There is no coordinate space branching involved.

That is, regardless of anything else, this loop would unroll to 3^7 = 2187 copies of itself at 7 iterations. As I understood it, this was the exact point of the explosive recursions warning?

Honest, I don't think it makes any difference in terms of recursion what components the branching goes into (except of course when it comes to memory management of the internal bitmap cache).

Explosive branching.ffxml
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
In other words this:

  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Is the same as this (at five iterations):

  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
As the above is a loop with just 3 components with one outgoing branching into two, I would draw the conclusion that it doesn't matter all that much that there is no coordinate branching, the loop becomes massive in any case, and even the fastest of components won't easily handle more than a few iterations.
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Sphinx, looking at it again, I am starting to think that due to multiple serial branching inside the loop of the Julia fractal there may even be (2^n)*(3^n+3^n)*(2^n+2^n), i.e. 6912 sample calls to the accumulator per pixel already at 3 iterations, which would certainly explain the slowness.
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
If this really is the case, might be good to have a soft warning on an outgoing connection within a loop if there is more than one connection?
  Details E-Mail
Vladimir Golovin
Administrator
Posts: 3446
Filters: 55
Probably yes, but we don't yet have any infrastructure for showing warnings on component's output.
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
(I'm at work now, so this will be a short comment)

If the sample cache is NOT working like it used to (or like it does outside looping context), then I fully understand why the filter is so slow (there are several branches and also in multiple orders).

My point is that it should work here. The loop concept is not worth much if we can't do simple sample copying smile:cry:
  Details E-Mail
Vladimir Golovin
Administrator
Posts: 3446
Filters: 55
Quote
If the sample cache is NOT working like it used to


The sample cache always worked this way, it just wasn't as noticeable because there was no repetition. We noticed it when we were rewriting sample cache to support Loops.
  Details E-Mail
Indigo Ray
Adam

Posts: 1442
Filters: 82
Let me get this straight. In general, the number of iterations ^ [the number of paths starting at "accumulated" and ending at "loop"] is the number of recursions and is roughly proportional to rendering time? smile:?:

In this filter, I use the same components two different ways. Both methods should render in about the same amount of time. The "bad" method has 5 iterations, but there are two paths starting at "accumulated" and ending at "loop", so there are 5^2 = 25 recursions. The "good" method has 25 iterations and only one path, so 25^1 = 25.

Loop Speed Test.ffxml
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
Vlad, is there some quick fix we can use to re-enable the cache hits? I'm thinking in lines of "place x component right after the accumulated component, place y component right before the loop accumulator input"?
  Details E-Mail
Vladimir Golovin
Administrator
Posts: 3446
Filters: 55
Indigo, yes, but I believe it's the other way around:

[the number of paths starting at "accumulated" and ending at "loop"] ^ the number of iterations
  Details E-Mail
Vladimir Golovin
Administrator
Posts: 3446
Filters: 55
Quote
Sphinx
Vlad, is there some quick fix we can use to re-enable the cache hits? I'm thinking in lines of "place x component right after the accumulated component, place y component right before the loop accumulator input"?


Unfortunately, no (or, rather, I'm not aware of any). The quickest fix is to go through get_sample() methods of ALL COMPONENTS, including the obsolete ones, and refactoring their use of a certain rendering_data struct according to the new policy, then re-testing them all so that a) their RGB output remains the same, b) the AAZones / AAEdges aren't broken and have the same pattern as before, and c) the rendering time when looped-with-an-exponential-recursion stays the same or is improved.
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
okay - I'll see if grouping and a script with custom sample cache can do the trick smile:-)
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
That was easy! No grouping needed. You should consider saving a few rainforests by at least adding proper caching at the accumulated output smile:-p

Native Julia Set.ffxml
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Sphinx, you're a genius! Sounds like you have just taken the "explosive" out of recursion with just one step (that likely no-one else in the known universe would ever have thought of).

smile:hammer: --> smile:eek: --> smile:loveff:
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
Now imagine getting that inefficient script out of there smile;-) Anyways it seems to work that Julia thing, however the normalized iteration ("Position") did not turn out as expected - we should see gray tones according to "bailout" (the threshold) iteration.. I don't get it smile:?:
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Hmm, yes, it seems a bit more complicated than just forcing the bitmap by Script. (And, if there was a built-in "Force bitmap" component, it would certainly help).

I tried to stick the Script into my iterative fractal tree (that has 3 internal branches) and it actually slowed it down smile:?: , so there is more to this than meets the eye. Perhaps the placement of the Script is more critical? Dunno, but hopefully we can find it out.
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
Not sure what that bitmap stuff is about. The custom sample cache script probably don't go well with spatial distorters (you probably need to place a new cache script at their outputs), or place copies of the cache script at the accumulated componet, one for each distortion "channel" (i.e. each new set of X,Ys passed down from the Loop Accumulated).
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Hmm, yes, tried that to no avail.

What I gather from what you said is because I have a different rotate value for the three branches, there's likely no gain in trying to cache the results?

But that's not really an issue since there are plenty of other things I can optimize in my fractal tree filter. The biggest problem was creating too many anti-alias zones to force almost the entire image area to be run through although set to "edges only". Fixing that took it down to 1/10th the previous render time. So a different problem, really.
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
"Force Bitmap": Wouldn't it help (in some cases) to have a component that rendered the downstream image as a bitmap so that subsequent calls would not have to go further down than the bitmap component to fetch the value? (Like is the case with some existing bitmap components, AFAIK)
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
Each iteration would require a new rasterization to a bitmap. That process itself is heavy and moreover it would require a lot of memory. Not sure its the way to go.

I wouldn't mind taking a look at your filter and see if I can figure out the caching options..
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
Ok, great, thanks. Here's the pared-down version. It runs okay up to about 8 iterations, probably pretty useless in the current form at any higher iterations (Although they are not that necessary in this case). It would certainly be interesting and useful to see if something can be done to speed it up at higher iterations, for it will definitely help in other recursion-style filters.

Loopy tree.ffxml
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
By the way, if you come up with some way to make each individual branch angle different, (without a Script and array) I'd be very happy smile:D . Right now it just duplicates a copy of the same pattern three times, so looks quite unnatural.
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
Ok, all those distorters destroy all caching options :-/ You have 3 separate coordinate branches (4 if we count the randomizer drain, but that probably has little impact). Those will branch out x3 for each iteration.. that REAL exponential explosions going on here smile:-p

I'm not sure there is a fix for this really, besides radical redesign. I'll let you know if I figure out anything interesting.
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
I thought that might be the case. Fortunately it is not really a problem with this filter, for there is no need for more than, say, 7 or 8 iterations at max, and it runs at an acceptable rate. I should be able to figure out an alterate way to create the tree branches so they aren't clones, this was primarily a rapid test for recursive loops.
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
If you can render the branches directly instead of transforming some fixed shape, that might help in both areas (i.e. performance and uniqueness of branches). Example: Some components have a rotation parameter - using that instead of a post rotation component will not create any new coordinate branch..
  Details E-Mail
ThreeDee
Lost in Space

Posts: 1672
Filters: 112
I better add my Non-overlapping Circles loop from here to this thread. It seems unjustifiably slow for all its simplicity.
  Details E-Mail
xirja
Idididoll Forcabbage

Posts: 1698
Filters: 8
This attached example seems to shed light on something amiss with the threshold in a loop. At 10 iterations the blend component is 20x faster than the threshold component? Usually the threshold is more efficient than the blend. smile:?:

Threshold Bug.ffxml
_____________________________________________________

http://web.archive.org/web/2021062908...rjadesign/
_____________________________________________________
  Details E-Mail
Sphinx.
Filter Optimizer

Posts: 1750
Filters: 39
Quote
xirja wrote:
This attached example seems to shed light on something amiss with the threshold in a loop. At 10 iterations the blend component is 20x faster than the threshold component? Usually the threshold is more efficient than the blend.


I think you're on to something - that is exactly the thing I'm doing with the Exit Loop thingie.
  Details E-Mail

Join Our Community!

Filter Forge has a thriving, vibrant, knowledgeable user community. Feel free to join us and have fun!

33,711 Registered Users
+18 new in 30 days!

153,531 Posts
+36 new in 30 days!

15,347 Topics
+72 new in year!

Create an Account

Online Users Last minute:

16 unregistered users.