Jump to content

Formula nodes: code readability comes at a price


Oakromulo

Recommended Posts

I would think that RT FIFOs are faster, but you can preallocate a queue by adding N dummy elements of correct size to the queue and then flush the queue.

That's very interesting. I've always tought the flush operation would reduce the queue size to zero. By the way, do you know if LV Queues are implemented internally as something like a C++ STL Queue or a Forward List?

http://www.cplusplus.com/reference/queue/queue/

http://www.cplusplus.com/reference/forward_list/forward_list/

Link to comment

That's very interesting. I've always tought the flush operation would reduce the queue size to zero. By the way, do you know if LV Queues are implemented internally as something like a C++ STL Queue or a Forward List?

http://www.cplusplus...ce/queue/queue/

http://www.cplusplus...t/forward_list/

I can't speak for RT FIFOs, but I have read that the normal queues are implemented as circular buffers. Not sure how/when re-allocation happens, but I assume that once the buffer grows in size, it doesn't shrink back down. Hence the N-element enqueue/flush trick.

Link to comment

I can't speak for RT FIFOs, but I have read that the normal queues are implemented as circular buffers. Not sure how/when re-allocation happens, but I assume that once the buffer grows in size, it doesn't shrink back down. Hence the N-element enqueue/flush trick.

It makes total sense. RT FIFOs are probably implemented as standard fixed-size arrays.

Link to comment

Oh no... same thing with the next critical part of the neurofuzzy controller algorithm! The machine learning algorithm (performance bottleneck) with primitive array operators is again 4x faster (and uglier) than the formula node version.

There are several things you can do to that formula node. The last time I checked (some years back), the formula node does no optimizing at all. You have to do that manually. For instance, the pow function is slow in any language. x*x = pow(x,2) mathematically, but x*x is much faster, x*x*x is faster than pow etc, etc. I use an ancient Maple (Maple R4) for that. A hopefully faster, but mathematically equivalent, formula node would (or could) be something like:


t1 = alpha*dedys;

t4 = t1*(y-y*s);

t6 = w/b;

t7 = x-c;

t8 = s*s;

t14 = t7*t7;

A[0] = c-t4*t6*t7/t8;

A[1] = s-t4*t6*t14/t8/s;

A[2] = p-t1*t6*x;

A[3] = q-t1*t6;

[/CODE]

Where the array is your result from the formula. I had to use array only for Maple to work.

Edited by bsvingen
Link to comment

Another major bug I found in the formula node. A program I have would nut run in LV 2011+. It would only run in pre 2011. I couldn't find out what was wrong, the results only gave NaN when in 2011+, but was OK in 2010. I eventually made a special "NaN finder" to track it down. The error was inside a formula node, and it was a major bug in LV. The formula node up and including 2010 did not work according to IEEE.

The function is z = (a/x)*exp(1/x) where a is a number from 0 to 1 (often, but not always 0) and x is a number from 0 - 1.5. When a = 0 the physical meaning should be z = 0. I thought this was mathematically correct because 0 * [any number ] = 0. In 2010 and earlier the result was 0 when a = 0 for any x (except x = 0), and everything was OK. The point is that this is not correct.

If x is less than approximately 0.00145, then exp(1/x) = Inf due to double precision. Then z = 0 * Inf = NaN (According to IEEE) while formula node in 2010 gives z = 0. In 2011+ this is fixed and the formula node gives correct result, z = NaN. But I have seen no mention of this bug, and no mention that it is fixed. Another problem with this is that if the formula node only calculates z = a * x, and a is 0 and x is Inf, the result is NaN also in 2010. So what exactly is going on inside the formula nodes is a great mystery.

Link to comment

So you 'Cant have your cake and eat it too'

Fast or beauty. Pick one.

(and I don't find the formula box 'beautiful' )

Ton

No free meal after all! At least there's Darin's Math Node to save development time...

Another major bug I found in the formula node. A program I have would nut run in LV 2011+. It would only run in pre 2011. I couldn't find out what was wrong, the results only gave NaN when in 2011+, but was OK in 2010. I eventually made a special "NaN finder" to track it down. The error was inside a formula node, and it was a major bug in LV. The formula node up and including 2010 did not work according to IEEE.

The function is z = (a/x)*exp(1/x) where a is a number from 0 to 1 (often, but not always 0) and x is a number from 0 - 1.5. When a = 0 the physical meaning should be z = 0. I thought this was mathematically correct because 0 * [any number ] = 0. In 2010 and earlier the result was 0 when a = 0 for any x (except x = 0), and everything was OK. The point is that this is not correct.

If x is less than approximately 0.00145, then exp(1/x) = Inf due to double precision. Then z = 0 * Inf = NaN (According to IEEE) while formula node in 2010 gives z = 0. In 2011+ this is fixed and the formula node gives correct result, z = NaN. But I have seen no mention of this bug, and no mention that it is fixed. Another problem with this is that if the formula node only calculates z = a * x, and a is 0 and x is Inf, the result is NaN also in 2010. So what exactly is going on inside the formula nodes is a great mystery.

I've been through a simpler, yet very annoying bug at LV 2010 when NI released that feature that enabled us to directly wire error clusters to a boolean operator. In the first release, it would always return false at every FPGA VI, no matter the cluster value. At the same time, I had a C Series module with a clock problem and I couldn't track the underflow error. A very skilled NI Support guy found the bug after almost a week full of compiles and equivalent code replacements. After that, no more "new" LV before SP1, just like Windows releases...

There are several things you can do to that formula node. The last time I checked (some years back), the formula node does no optimizing at all. You have to do that manually. For instance, the pow function is slow in any language. x*x = pow(x,2) mathematically, but x*x is much faster, x*x*x is faster than pow etc, etc. I use an ancient Maple (Maple R4) for that. A hopefully faster, but mathematically equivalent, formula node would (or could) be something like:


t1 = alpha*dedys;

t4 = t1*(y-y*s);

t6 = w/b;

t7 = x-c;

t8 = s*s;

t14 = t7*t7;

A[0] = c-t4*t6*t7/t8;

A[1] = s-t4*t6*t14/t8/s;

A[2] = p-t1*t6*x;

A[3] = q-t1*t6;

[/CODE]

Where the array is your result from the formula. I had to use array only for Maple to work.

Yeah... I've forgotten about the lot of possible optimizations and redundancies inside the node. Anyways, after this topic, I'll save the formula nodes for only when performance is not so much of a concern or those meet-the-godsent-manager moments: "hey, your code is as messy as your table".

Link to comment

Do you have access to the math script node? It would be interesting to know how that performs by comparison (and may try it myself when I get time). I believe it still falls a little short of pure G implementations but as the flagship textual math node now I believe it would be much closer to it than the formula node.

Link to comment

Just did a quick test but seems much slower! Attached is the mathscript node if anyone can spot if I have done something wrong.

edit: some changes where it needs to be vector functions instead of matrix functions '. In front of the operator' brought it it 12x slower. I will have another look later to see if there is anything else I missed but the primitives are still looking pretty good

evalSugenoFnodeDBL.vi

Link to comment
  • 1 month later...

Just for reference, one reason the formula node is often slower than the equivalent primitives is that it doesn't go through DFIR optimizations, which we've spent a lot of time on since LabVIEW 2009.

 

Now the MathScript node does go through DFIR, etc., so I'm surprised to see it being slower - you may want to talk to someone who knows more about that to see what the deal is.

Link to comment

The formula node contains a simple text style parser with a subset of the C syntax. The resulting code is compiled into the VI but it has not optimizations at all. After all the LabVIEW developers did not intend to include the entire LabWindows CVI compiler (most likely they didn't even loan code from the CVI compiler for this). NI never said the formula node would be highly optimized but always maintained that it is for the text inclined to be able to define mathematical calculations without the need to translate everything into LabVIEW nodes, but performance of the calculation will be likely always somewhat slower than the equivalent code done with LabVIEW nodes. LabVIEW definitely has not optimized over any structure boundaries in the past and even less over VI boundaries.

 

While LabVIEW recently seems to have started to also do some optimizations over structure boundaries, I would bet that the formula node is not a candidate for this until they change it to compile to the new intermediate DFIR graph that gets then fed into the LLVM compiler for actual compilation of the target code. And while such a change would be technically very nice, it is probably low on the list of things todo, because it is a considerable task, but gives little bang for the buck in terms of marketing it as a feature.

 

Another tangent to this is also that if someone insists on doing complicated formulas in text and is concerned about squeezing the last grain of performance out of it, then he very likely is to go to an exernal library anyhow, since that gives him every choice in what language to choose as well as which compiler toolchain, possibly with highly optimized code generator and/or runtime libraries.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Similar Content

    • By Porter
      View File LV muParser
      LV-muParser provides a simple LabVIEW API for muParser fast math expression parser.
      A modified version of muParser v2.2.5 is included. It will be installed to your "<LabVIEW>\resource" directory. I have added support for the "!" (not) operator as well as added ":" as a valid character for variable names.
      You will find the muParser API in the functions palette under "Addons > LAVA > muParser"
      muParser: http://beltoforion.de/article.php?a=muparser
      LV-muParser source on github: https://github.com/rfporter/LV-muParser
      Submitter Porter Submitted 08/25/2017 Category General LabVIEW Version 2015 License Type BSD (Most common)  
    • By AnnihilationSpectrum
      Hi, I'm new in Labview.  I work as an intern. I have a formula for fitting a spectrum. The left side of the spectrum is higher than the right side. There's a background on the left side.I need to lower the level of the left side to the right by applying this formula. It should be a Gaussian curve.  I need help. Who can help me?


    • By Taylorh140
      I have never gotten the performance that I desire out of the 2D picture control. I always think that it should be cheaper than using controls since they don't have to handle user inputs and click events etc. But they always seem to be slower.
      I was wondering if any of the wizards out there had any 2d picture control performance tips that could help me out?
      Some things that come to mind as far as questions go:
      Is the conversion to from pixmap to/from picture costly?
      Why does the picture control behave poorly when in a Shift register?
      What do the Erase first settings cost performance wise?
      Anything you can think of that are bad ideas with picture controls?
      Anything you can think of that is generally a good idea with picture controls?
    • By Porter
      LV-muParser provides a simple LabVIEW API for muParser fast math expression parser.
      A modified version of muParser v2.2.5 is included. It will be installed to your "<LabVIEW>\resource" directory. I have added support for the "!" (not) operator as well as added ":" as a valid character for variable names.
      You will find the muParser API in the functions palette under "Addons > LAVA > muParser"
      muParser: http://beltoforion.de/article.php?a=muparser
      LV-muParser source on github: https://github.com/rfporter/LV-muParser
    • By Manudelavega
      A few years ago I wrote my own equation computing algorithm for my company's flagship software. The user will write equations using variable names and constants (for example a=2*b+3), and those equations run continuously every 100ms.
      The pros
      The user can add Min and Max expressions inside the equation. For example a=Min(b,c)+2. The syntax supports parenthesis. For example a=3*(b+c). The limitations
      You can have several operators but their priority is not respected. For example the result of 1+2*3 will be 9 instead of 7. The user has to write 1+(2*3) or 2*3+1 to get the correct result. You can't put an expression inside a "Power" calculation. For example, you can do a+b^c but you can't do a^(b+c). You would need to create a new variable d=b+c and then do a+d, so now you have 2 equations running in parallel all the time instead of 1. There is no support (even though it wouldn't be hard to add) for sin, cos, tan, modulo, square root... I am now thinking of using a built-in LabVIEW feature (or one the community might have created )  in order not to reinvent the wheel completely. Surely I am not the only person who needs to compute equations.
      I looked at vi.lib\gmath\parser.llb\Eval Formula String.vi and it seems to answer 90% of my needs, it is simple to use, but it doesn't support Min and Max expressions and writing a hybrid system would be complicated.
      What do people use out there?
      If I need to reinvent the wheel, I found interesting resources such as https://en.wikipedia.org/wiki/Shunting-yard_algorithm and https://en.wikipedia.org/wiki/Operator-precedence_parser so I think I can pull it off, but it's going to be very time consuming!
      Cheers 
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.