Optimising functions for speed

Started by Mr_Lamppost, November 16, 2007, 08:30:54 PM

Previous topic - Next topic

Mr_Lamppost

I have been intending to ask this for a while but does anybody know which is faster; Multiply or Divide?

It has always been a tradition in Programming / scripting to use a multiply rather than a divide as this is faster to execute.  However I have read that POV-Ray, which creates scenes from an interpreted scripting language, converts Divides to multiplies at the interpretation stage.  Allowing users to use divide without a loss of efficiency; I can't definitively confirm this but from practical experience it appears to be true.

As TG2 also uses interpreted scripts (Look at one of your TGDs using a text editor), I am wondering if the same is true? 

Initially I had no problem with multiplying by small fractions but as my node networks become more and more complex I am finding that I am using Divide Scalar nodes more as it is easier to keep track of what is going on when dealing with scales if I use divides.  Example: I want the features derived from a Perlin 3D Scalar to be 64 times as large as the default it is easier to divide the Get Position by 64 than to multiply it by 0.015625 (1/64).  :)   I have made a quick test with a simple node setup with the following result:


Version 1 – Multiply = 04:47

Version 2 – Divide = 04:52


Times based on a default settings Full Render.

While there is a small difference I don't believe that this is conclusive as any number of things could account for the discrepancy;  What were the active components of QuickTime or RealPlayer doing? (Can You install without them?). Did my security software download an update during the render?  As you may guess I am using a User friendly (F* Efficiency), Bloatware "Operating System" from our old friend Bill.   >:(

Here are the Node graphs and the output.

Smoke me a kipper I'll be back for breakfast.

Harvey Birdman

I think you're being overly concerned with minutae whose effect on rendering time is negligible compared to other considerations. The difference between the two times you've measured is less than 2%. Any number of variables in the normal operation of your system could easily account for variations of that magnitude. And the tgd isn't a script - I believe it's XML.

I'd think you'd need a very, very large network to document any repeatable, significant performance difference based strictly on the function of those nodes being multiply versus divide.

IMHO.

green_meklar

QuoteIt has always been a tradition in Programming / scripting to use a multiply rather than a divide as this is faster to execute.
That's what I've heard as well. But I would also echo what Harvey Birdman said; the difference in speed is probably so small that ease of use would usually take priority.
QuoteHowever I have read that POV-Ray, which creates scenes from an interpreted scripting language, converts Divides to multiplies at the interpretation stage.
Then if it's not the division slowing the program down, it's the conversion. At any rate it seems that it seems it would be unusual for multiplication to be slower than division, while the opposite is apparently often true.
You know what's worse than not being able to do anything right or make anything good? Not being able to blame it on anyone but yourself.

Mr_Lamppost

Quote
QuoteHowever I have read that POV-Ray, which creates scenes from an interpreted scripting language, converts Divides to multiplies at the interpretation stage.
Then if it's not the division slowing the program down, it's the conversion. At any rate it seems that it seems it would be unusual for multiplication to be slower than division, while the opposite is apparently often true.

It is precisely because Multiply is faster than Divide that conversions are made.  Doing this allows the user to specify values like 1/3 1/7 17/19 pi/6 etc.  without having to worry about the resultant increase in render time caused by processing all those divides. 

The test scene was very simple, probably too simple to distinguish an actual performance hit from the general variation caused by all the background processes operating under Windows.  I am running another test with a more complex scene. 

I have a couple of worlds where a divide or several divides are used at an early stage as in the example, If every subsequent operation has to make reference to position through that divide node then the potential hit on render time could be significant.  Obviously if there is no significant difference between using a Multiply or a Divide then all well and good and we can happily pepper our complex function derived landscapes, textures and cloud distributions with Divide Scalar nodes in the knowledge that the render time is not going to be greatly effected.  With high quality renders taking days even a 1% overhead becomes significant.

Smoke me a kipper I'll be back for breakfast.

mogn

There might be a reason, why division is slower than multiply. Matt says the he uses an epsilon algorithm to
prevent division by zero (i.e. replacing division by zero with a multiply with a big number).

jo

Hi,

It's true that divides are often slower than multiplies, in general. At present TG2 doesn't do any optimisation or compilation of nodes as a prepass to rendering or anything. Without doing this it wouldn't be possible to optimise divides because to replace a divide with a multiply you first need to calculate a reciprocal. Doing that every time through a division node wouldn't be any sort of optimisation. Maybe in the future TG2 will be able to compile node networks before rendering so they will be more optimised, but it will be a fair bit of work.

I suppose if you were keen and you were dividing by constants you could work out the reciprocal and change the division by the constant to multiplication by a new constant set to the reciprocal. For example, instead of dividing something by 2 I often just multiply it by 0.5. To justify the effort you'd need to verify that it was making a difference in a typical scene, and for that you'd need to run the scene at least 6 times ( 3 using division, 3 using multiplication ) to make sure you're getting consistent results. When I say "typical scene" I mean it isn't much use just setting up a simple network and comparing it because in a typical scene any difference could just be swallowed up by all the other stuff which is going on.

The OP mentioned something about TG2 using interpreted scripts. It doesn't. The project files are a stored representation of the nodes used in a project, and TG2 turns them into something else ( C++ objects ) when it loads the file. If you load a file then add a new node, that node isn't written in the file until you save it again, so as you can see the file can hardly be used as a script. The project is just a data file which happens to be written using human readable XML formatting.

Regards,

Jo