LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Swap Vector Element function

Solved!
Go to solution

GregS

It appears, that you may be right. I've just made quick test on very big array (100 000 elements), containing a cluster of different data types (I64, DBL, Boolean, LV String, Path, VI Reference and array of I32). When swapping each array element with new one in the loop, Replace Array Subset gives execution time of ~70 ms, whereas Swap Vector Element gives ~30 ms. You can do this test on your own (look at the attachment).

It's really interesting if SVE does real pointer swapping, not the moving of data itself. Think, assembly listing might shed some light on it, but now I'm too busy to go for it.

0 Kudos
Message 11 of 15
(1,566 Views)
0 Kudos
Message 12 of 15
(1,543 Views)

You should be able to duplicate this functionality with an In-Place Element Structure (using an array index) and the Swap function that is available. I don't have time right now but I'd expect that to be identical in speed to the function under discussion.

0 Kudos
Message 13 of 15
(1,539 Views)

Hooovahh

I have seen a half of these links, but thanks for posting them anyway Cat Happy Yes, some instruments are very unstable. I tried those DVR VIs and they've been crashing LabVIEW very often. Also tried to figure out, what was designed that Transpose 1D Array for. Have not succeded. The rest looks interesting, but I treat these unfinished nodes with caution and do not anchor one's hope to it for solving my tasks. It's just for fun, I think.

 

nathand

In Place Element Structure gives almost the same result as Swap Vector Element function. SVE works a little faster - the difference is approx. 5-8 ms. My guess what it has not ever been published: its functional is already realised in In Place Element Structure, so the developers didn't want to introduce duplicate function in LabVIEW. Don't know, if it's true though.

0 Kudos
Message 14 of 15
(1,526 Views)
Solution
Accepted by topic author dadreamer

Well, 5 years later I found time to look inside SVE node, so now I can clarify, what it does. The node just calls this internal function (also available in both labview(v).lib and lvrt.dll):

void VectorSwapReplaceElt(const void *arrDataPtr, int32_t sizeofDataType, int32_t numBytesToMove, int32_t arrSize, int32_t *initSwapIdx, void *initSwapElt);

where

arrDataPtr - the input array's data pointer (vector / returned vector of SVE);

sizeofDataType - how many bytes one element occupies, e.g. sizeof(uInt32);

numBytesToMove - how many bytes to move/swap, for SVE it always equals to sizeofDataType;

arrSize - size of the input array;

initSwapIdx - pointer to index of the array's element to swap (index / returned index of SVE);

initSwapElt - pointer to the element to swap with (element value / swapped element value of SVE).

swap2_BD.png

2020-05-11_22-34-10.jpg

 

VectorSwapReplaceElt does in turn something like the following:

void MySwap(uInt32* arrDataPtr, int32 sizeofDataType, int32 numBytesToMove, int32 arrSize, int32* initSwapIdx, uInt32* initSwapElt)
    {
        if (*initSwapIdx >= 0)
            if (*initSwapIdx < arrSize)
            {
                uInt32* arrEltToSwap = ((uInt8*)arrDataPtr) + (*initSwapIdx * sizeofDataType);
                //if number of bytes is multiple of 4, then swap everything "manually"
                //else use SwapBlock func
                if (numBytesToMove % 4 != 0) SwapBlock(arrEltToSwap, initSwapElt, numBytesToMove);
                else
                {
                    if (numBytesToMove > 0)
                    {
                        int32 numOfChunks = ((numBytesToMove - 1) >> 2) + 1; //get the number of 4-byte chunks to swap
                        do {
                            int32 tempSwapElt = *initSwapElt;
                            *initSwapElt = *arrEltToSwap;
                            *arrEltToSwap = tempSwapElt;
                            initSwapElt++;
                            arrEltToSwap++;
                            numOfChunks--;
                        } while (numOfChunks > 0);
                    }
                }
            }
            else *initSwapIdx = -1;
        else *initSwapIdx = -1;

As you could see in the code, if numBytesToMove (which equals to sizeofDataType for SVE) is 4, 8 and so on, this logic moves the data by 4-byte "chunks" (by 32-bit integers, in other words), but when numBytesToMove is 1, 2, 3, 5 etc., SwapBlock (LabVIEW Memory Manager function) is invoked and does the rest of the work. As for LabVIEW 2019, on which I've been testing this, I could say, that VectorSwapReplaceElt might not use that 4-byte copying at all and pass all the parameters to SwapBlock without a peep, because SwapBlock already contains the same logic: when number of bytes to move is a multiple of 4, it uses 4-byte blocks, else it copies data byte by byte. Maybe SwapBlock has not always been like that, but currently I have not tested it on anything earlier than LV 2019.

Taking all this into account, I conclude that VectorSwapReplaceElt is no more dangerous than officially supported SwapBlock function, even though with improperly formed parameters both functions could easily crash LabVIEW. I assume, we as experienced coders, do everything right, so it's not our case. 😊

As for SVE node, it's safe to be used as well (not supported though), except one specific condition, when its element value input has data representation different than vector (aka array) element. In this case we see a coercion dot on element value input, but it doesn't do anything and the original value is passed into VectorSwapReplaceElt. If we set vector / array's representation to something smaller than element value's representation and also set index to the end of the array, then we'll be rewriting the memory behing the array! Here's the example for how LabVIEW could easily be crashed with SVE:

swap-bad_BD.png

I'm sure, I don't need to explain, why that happens - just look at C code above. Seems like some additional check should be introduced to the code or the dot should be "activated".

Also it worth mentioning that SVE doesn't take another array as element value input, but VectorSwapReplaceElt allows that. You just need to set numBytesToMove to the size of your array and adjust initSwapElt input in CLFN. If done, several elements are swapped by one call (the output array gets new elements at given index and initSwapElt array gets old elements). Pretty the same thing as Replace Array Subset does. So, this is one more thing for SVE that might be enhanced, if it wouldn't be an abandoned node.

Among other things I had a quick look at the asm listings for SVE, RAS and In Place Element structure. None of them do pointers swapping. They all move data by bytes. RAS does this with a few instructions, In Place runs about a dozen of instructions (because of additional checks) and SVE like In Place spends some time for checks and for external calls as well. Still no real advantages to use SVE, unless you really want to, but it's clear how it works at least.

0 Kudos
Message 15 of 15
(939 Views)