10-21-2015 03:32 AM
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.
10-21-2015 01:18 PM
Yes for those interested there is lots of unfinished pieces in the form of primitives:
https://lavag.org/topic/15894-recomposeunlockdatavalref-and-recomposevariant/
https://lavag.org/topic/15895-new-vi-objects/
https://lavag.org/topic/16733-floating-point-equal-primitive/
I'd assume most are either not complete, not documented, or are unstable in same uses. Paraphrasing a bit but "Unfinished features of LabVIEW is like catnip laced with poison."
Unofficial Forum Rules and Guidelines
Get going with G! - LabVIEW Wiki.
16 Part Blog on Automotive CAN bus. - Hooovahh - LabVIEW Overlord
10-21-2015 01:31 PM
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.
10-21-2015 02:46 PM
Hooovahh
I have seen a half of these links, but thanks for posting them anyway 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.
05-11-2020 01:52 PM
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).
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:
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.