06-15-2009 11:28 PM - edited 06-15-2009 11:32 PM
I didn't really want to hijack this idea suggestion to discuss the best practices for dealing with coercions.
This post is just a starting point. Feel free to add to it! 🙂
Here are a few slighly edited snipped from the earlier discussion:
InternationAL:
...I don't know how many times I've dropped a million conversion functions til I found the one that made the dot go away.
(editor note: this make it seem that it is important to get rid of coercion dots at all costs and the best solution is adding a conversion bullet :D)
Altenbach:
A coercion dot is not always worse than the conversion function and there are cases where the coercion is actually faster and more efficient than the explicit conversion.
I tend not to insert explicit conversion unless the output branches into several coercions. Especially with scalars, the difference is negligible anyway.
Here's a case where coercion is significantly faster than explicit conversion. The conversion forces another buffer allocation!
(code in this example simply zeroes all negative values of a 2D array)
(EDIT: actually, I marked it wrong. The upper code is 50% faster, thus the lower 33% slower. Still significant! Try with a 2000x2000 array, for example.)
You are collapsing my entire foundation of data coercion in LabVIEW. You mean, I NEED to leave coercion dots on large datatypes??? It is distressing to think that I need to benchmark "bad" programming practice against "good" because the "bad" may be more efficient.
From the help file on coercion dots: "Coercion dots can indicate points where a VI uses more memory and increases its run time." From altenbach: "Coercion dots can indicate points where a VI uses less memory and decreases its run time."
Why does the compiler not interpret both snippets the same?
Here are some of my ideas to jump start this new discussion thread:
A coercion dot simply means that there is mismatch betwen what a function wants and what it gets.
Mindlessly throwing in a conversion operation is just covering things up with a bandaid. It's not solving the problem, but just deals with the problem more explicitely. The data still needs to be converted and possibly a new buffer allocated. You don't gain much! Of course if the wire branches to several coercion dots, converting once possibly makes sense.
The correct way to deal with coercion dots is deciding on a better representation for the data from the ground up an solve things upstream. Change the representation of the control itself! Rewrite the subVI to give the correct output repesentation! Whatever is most logical. 😄
Also remember that the newest LabVIEW versions allow output configuration for many functions, so you can configure it to give the correct datatype to eliminate coercions. (In LabVIEW 8.6, right-click e.g. on "Add" and select properties...output configuration). I have not really explored what the penalties are for this.
Some basic functions such as the multiply node in the image of the previous post are highly optimized and can apparently do the multiplication of the DBL and I16 Array "in place", re-using the DBL array, without the need to convert the I16 array to a new DBL array first.
06-16-2009 12:21 AM
Hosana!
Coersion dots are not the devil incarnate! But, (take a deep breath through the nose) my LabVIEW.ini hs declared them to be the (breathe slowly out through the mouth) UGLIEST shade of green I can find on my color pallet.
I NEVER want to miss a coersion! but, as Forest Gump may have said, "coersion happens! :
The trick is to KNOW when and what the effects are. <ctrl>H over the wire and you will know more. Learn the details of LV types and you'll be safer, right-Click for more details... and read the definitions!
Practice safe coersion!
06-16-2009 05:53 AM
Hi,
Probably "coercion logic" from traditional languages will be more useful?
For example, in C we will get following warning by "coercion":
The same in LabVIEW - widening and narrowing coercions:
safe coercion from int to double marked as green point
unsafe coercion from double to int marked as red point
(of course, the user shall be able to change type of output in this case)
Just an idea...
Andrey.
06-16-2009 06:36 AM
But, but...
I deal with large data sets all the time, and have followed the good programming guidelines set down by NI and diligently gotten rid of all coersion dots. It concerns me to think this may be slowing things down. Yes, where practical, it would be a Good Thing to rewrite the source of the data to be the "correct" data type, but sometimes (often, if sharing code, or attempting to adhere to code reuse practices) that isn't possible or practical.
So is the key to look at where buffers get created?
Cat
06-16-2009 07:19 AM
06-16-2009 07:51 AM
Nice post Christian!
Yes I agree with all of the above. I can not recall a case where using the the explicit conversion nodes every out performed the implied coercion. You have pointed out another one of those cases where a "law" is better broken than blindly observed.
Stepping back and waxing philosophical
With LV we are generally freed from the details of memory management. So rather than managing our memory explicitly, we manage it implicitly. The "gestures" (code constructs) we use mean a lot and even sublte gestures (the order in which we operate on data buffers) can have a big impact.
But for performance questions, our biggest concerns is how we are using the CPU. WE intend to use it to get some type of result but along the path to find that result we could take mode or less direct routes. If we find ourselve packing and un-packing our back-packs before and after every step we take (moving data between buffers via the CPU) our trek will take longer.
So to master the taming of the animal LabVIEW we have to learn how it interprets our gestures and watch it closely to ensure it is "doing what we want and not what we said".
This is one of the reasosn I greatly value the experience I gained working on the Dictionary Challenge and other such challenges over the years.
There is nothing like a week-end of bench-marking with a case of beer and no distractions to make your code faster.
Ben
PS For others that wnat to learn to develop faster performing code, find a thread where Christian has helped someone tweak their code. Run bench-marks for all of the version in the thread and try to write your own that runs faster than his (I actually did that ONCE, but it was a corner case). You may not beat him but you should learn something as a result of the exercise.
11-24-2010 08:48 AM - edited 11-24-2010 08:49 AM
The idea is generally not to get rid of coercion dots by replacing them with coercion functions. The idea is to get rid of them by changing your diagram in such a way that a minimal amount of coercions are necessary.
Functionally a coercion is simply an implicit conversion and nothing more. It can indicate a fundamental problem in itself sometimes (loosing accuracy or such things) and it will always use CPU and memory resources, but so does the explicit conversion. So getting rid of a coercion by using a conversion function is in many (most?) cases just a visual bandaid with no actual benefit at all.
And the unsafe coercion from double to int as shown in the C example should not really happen with LabVIEW primitives since they all adapt to the largerst datatype connected to it. It can be a problem with subVIs however (and some selected primitives that take specific integer inputs as that is mandated by the input function - ever had a loop execute half a time?) as they usually don't adapt (unless it is a polymorphic and there is a version that supports the larger size).
With the introduction of int64 however there is a potential problem with this always adapting to the larger size since the double can not possibly represent every value an int64 could be and vice versa
07-10-2012 03:00 PM
So I thought I was being clever and have instead been eaten by coercion dots.
I wanted to use an array of values where each index in the array has a particular meaning. Instead of constantly referring to a table to see which index is what value, I thought I would make an ENUM. Then in developer land when I need such and such a value, I can index the array with the enum and get what I want.
Except this causes a Coercion dot on the index input of the Index Array function. (LV 2009 SP1)
Even if the underlying data type of the enum is I32, as is the index input, there is still a coercion dot.
Ring controls do the same thing.
I am in whole hearted agreement that coercion dots are best avoided by using the data structures appropriate to your task, but Really?!?!? I can't use an type def enum to index an array? That is bad design?
Bummed and lookin for different data structures...
07-10-2012 03:08 PM
I've used typedef enums to be an indexer for the Index array function. I have not seen any particular problem. Yes you get a coercion dot. But coercion dots aren't inherently bad. It is just an indication that there is a change in the way the data is being interpreted. In the case of an Index array, it is expecting an I32 numeric. You just happen to be providing it with an I32 enum, basically a numeric with other additional information overloaded on it. So it is coercing that data from the more informative I32 enum to the basic I32 integer. You shouldn't have any problems in your VI with this particular coercion.
07-11-2012 08:27 AM
clendon.gibson@canrig.com wrote:
So I thought I was being clever and have instead been eaten by coercion dots.
I wanted to use an array of values where each index in the array has a particular meaning. Instead of constantly referring to a table to see which index is what value, I thought I would make an ENUM. Then in developer land when I need such and such a value, I can index the array with the enum and get what I want.
Except this causes a Coercion dot on the index input of the Index Array function. (LV 2009 SP1)
Even if the underlying data type of the enum is I32, as is the index input, there is still a coercion dot.
Ring controls do the same thing.
I am in whole hearted agreement that coercion dots are best avoided by using the data structures appropriate to your task, but Really?!?!? I can't use an type def enum to index an array? That is bad design?
Bummed and lookin for different data structures...
Don't be bumbed and stop looking, you found what you wanted.
As I posted earlier in this thread, the coercion dot version can often run faster than the same code with explicit conversions used.
As Ravens Fan posted (and was written above) teh corecion dot only tells us something is different between the source and sink of the wire. SOMETIMES the corecion requires duplicating the data on the wire but NOT ALWAYS.
Corecion dot != slow
Ben