LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Darin.K

Swap Array Elements Primitive

Status: New

Is it immediately obvious to you what the following code does?

 

SwapArrayElements.png

 

This rats nest simply swaps two elements in an array, a very common operation when trying to operate on a large array in-place.  The In Place Element Structure helps the looks a little, but I find the performance to lag when used in a tight loop, you know, the kind you encounter when you are trying to operate on large arrays.

 

SwapArrayElementsIPE.png

 

I would like a simple primitive (sorry too lazy for a picture) which simply swaps two elements in an array.  It should be similar to the Replace Array Subset function, except for two sets of index inputs and no subset input.  If you want to really make my day be sure to allow disabled inputs to swap rows and columns in one shot for 2D arrays, or pages or volumes or whatever in higher dimensional arrays.

22 Comments
Darin.K
Trusted Enthusiast
Neither you or I can fully answer that right now, it depends on the relative speed of the swap and the comparisons. The cost of speeding up the no op cases is an additional overhead in all cases. Assuming the speedy in place swap is fine with equal indices, I say skip the check for ultimate performance. If your algorithm is heavy with equal indices you can add a check, or you can use the IPES.
altenbach
Knight of NI

I agree this would be a great addition to the array palette. It could have been useful in the old median challenge to implement "quickselect" (I can no longer find the forum discussion. Has it disappeared??).

 

I don't fully understand the use of "swap values" in your picture. Except for the conditional boolean input (which could be useful), how is it different from just crossing the wires? Since arrays need to be contiguous in memory, it ultimately cannot do the swap operation without copying the values to a new memory location. (I have not benchmarked).

AristosQueue (NI)
NI Employee (retired)

> it ultimately cannot do the swap operation without copying the values to a new memory location.

 

Actually, yes it can, using assembly instructions to directly swap the bytes or multiple XOR operations (depending on operating environment) which are generally faster than copying to a third location.

 

> I don't fully understand the use of "swap values" in your picture. Except for the conditional boolean input

> (which could be useful), how is it different from just crossing the wires? Since arrays need to be contiguous

> in memory, it ultimately cannot do the swap operation without copying the values to a new memory location.

> (I have not benchmarked).

 

The difference is easy to explain. The reason behind the difference is fairly hard.

 

Just swapping the wires will create two data copies. Using the swap primtive will create zero data copies.

 

The following is *not* my area of expertise. This is my understanding from the compiler team:

The LV compiler always tries to generate the most efficient code it can while maintaing thread safety and functional correctness. The more LV can glean from your diagram about what you're intending, the better the code can match that intent. Merely swapping the wires does not necessarily tell LV enough to realize you're swapping values. Yes, in the trivial case shown here, LabVIEW could in theory detect this particular wiring configuration and just do the swap, but it couldn't in the general case (modifications of values by nodes along those wires, passing through a case structure, etc). This is a fundamental limitation of dataflow syntax, at least as we understand the computer science today. Rather than include code for this special case and still leave the general case as a problem, the swap priimitive was introduced. It allows you, the programmer, to give further information to the LV compiler about what you're doing with those values, which lets it improve the compilation. If users get used to always using the swap prim, even in the trivial case, there's never a question of "do I need this in this case or will LV figure it out?"

Darin.K
Trusted Enthusiast

I'd be lying if I said the reason that the swap primitive had entered my toolbox was the efficiency, I started using it because I really hate crossing wires, especially in the IPES case because you can not shift the terminals.  This means that you need extra bends to avoid serious overlap, not just the required crossing.  Then I start to learn that they not only look good, but they can be very useful in some cases, that is a total win: form+function.  This is like the variant attributes, I liked them because of their convenience, then I learned to love them for their efficiency.  It really works, you can get users to write good code by making the best looking code also the best working code.

 

> Actually, yes it can, using assembly instructions to directly swap the bytes or multiple XOR operations (depending on operating environment) which are generally faster than copying to a third location.

 

I see conflicting reports on the speed of the XOR swap versus the naive swap.  The true answer probably lies in the efficiency of the LV compiler as there are ways to optimize the naive swap (assuming the compiler knows it is a swap going on).  Plus as I keep harping on, the naive swap is safe for self-swapping, XOR is not.  Overall I trust the compiler team to give me something which is safe and fast.  (To date I can really only think of one primitive that I have beaten with equivalent G code.)

 

For the curious, here is a G implementation of the XOR swap:

XOR Swap.png

 

I think the reasoning for my proposed primitive is very similar to that for the swap primitive, I want the LV compiler to know exactly what I am doing and I rely on the compiler team to have implemented it in a reasonable fashion.  Added bonus, look at all of those wire bends and crossings that can be removed.

 

Next up, I need to sprinkle in a few 'Always Copy' nodes so I can get the AQ explanation for that one. 

 

 

AristosQueue (NI)
NI Employee (retired)

> Next up, I need to sprinkle in a few 'Always Copy' nodes so I can get the AQ explanation for that one. 

 

My best summary on that one: Never use it unless you have been to the performance optimization customer education course, you are doing a hide-the-dots project, you think you've found a situation that LV should handle better, and you have verified it by strenuous performance testing and/or submitting it to an NI AE who has throroughly investigated it.

 

The LV compiler keeps getting smarter and although a couple years ago there were interesting cases for that primitive, to the best of my knowledge the compiler found ways compensate for all of them so it no longer needs that hint. That's not to say there aren't other even more exotic situations out in the world -- there probably are -- but I don't know of any.

altenbach
Knight of NI

We had several cases in the past where the "always copy" prevented incorrect output, presumably by preventing an ill advised internal compiler optimization. 😄 Can we assume that all these are now fixed in 2011 and "always copy" is no longer needed?

AristosQueue (NI)
NI Employee (retired)

> Can we assume that all these are now fixed in 2011 and "always copy" is no longer needed?

 

Nope. I said all the ones *I* knew about were fixed. That's far outside my baliwick.

Darin.K
Trusted Enthusiast

Always Copy to the rescue again!

 

http://lavag.org/topic/15069-lv2010-weirdness/

dadreamer
Active Participant

I know, it won't help a much and it's not so neat looking as that In Place Structure piece, but here's one more way to swap two array elements:

Example_VI_BD.png

 

Likely not much of a reason to ever discuss this idea anymore, as Classic LV isn't a main priority nowadays. But AFAIK NXG also lacks the ability to easily do this swap, so the whole idea seems to be still actual.

wiebe@CARYA
Knight of NI

What's the name of that primitive? Is it new?  It's Swap Vector Element. Not new. But nowhere on the palette (in LV18)?

 

In a .vim it doesn't matter much how it looks.