Neil Pate Posted May 11, 2021 Report Share Posted May 11, 2021 I guess it is expected if you think about how the arrays are laid out in memory, but still interesting to confirm. For the eagle eyed I know my two loops will not actually produce the same result, but I don't think this should change the conclusion. Quote Link to comment
Darren Posted May 11, 2021 Report Share Posted May 11, 2021 Do you see similar results when running the benchmarks separately, i.e. one at a time in separate VIs as opposed to in parallel in the same VI? Quote Link to comment
dadreamer Posted May 11, 2021 Report Share Posted May 11, 2021 21 minutes ago, Neil Pate said: I guess it is expected if you think about how the arrays are laid out in memory, but still interesting to confirm. Maybe then you will find that VI interesting as well. I made that to compare different methods to replace rows/columns in the array (four known at the moment). Quote Link to comment
Neil Pate Posted May 11, 2021 Author Report Share Posted May 11, 2021 1 hour ago, dadreamer said: Maybe then you will find that VI interesting as well. I made that to compare different methods to replace rows/columns in the array (four known at the moment). Risky click of the day running that VI! But hey, life is short so I tried. My Russian is a bit rusty but I guess you came to a similar conclusion? Quote Link to comment
Neil Pate Posted May 11, 2021 Author Report Share Posted May 11, 2021 1 hour ago, Darren said: Do you see similar results when running the benchmarks separately, i.e. one at a time in separate VIs as opposed to in parallel in the same VI? Yes I did. Actually my first benchmark was just to make the change manually in the VI and re-run it. The results are the same. Sorry my picture was not good, if you look closely I introduce some forced data flow from the first structure to the second so that they do not run in parallel as I did not want to bias the results in any way. Quote Link to comment
dadreamer Posted May 12, 2021 Report Share Posted May 12, 2021 (edited) 10 hours ago, Neil Pate said: My Russian is a bit rusty but I guess you came to a similar conclusion? Yeah, I guess it's obvious for (almost) every programmer. And well illustrated by the 4th method with MoveBlock call. Looking at that one might say, this is how the replace operation is made internally. By the way it's possible to speed up MoveBlock method a little disabling the wrapper generation. But still it is inferior in speed to the native methods (i.e., Replace Array Subset and In Place Element Structure). Edited May 12, 2021 by dadreamer Quote Link to comment
Neil Pate Posted May 12, 2021 Author Report Share Posted May 12, 2021 11 hours ago, dadreamer said: Yeah, I guess it's obvious for (almost) every programmer. And well illustrated by the 4th method with MoveBlock call. Looking at that one might say, this is how the replace operation is made internally. By the way it's possible to speed up MoveBlock method a little disabling the wrapper generation. But still it is inferior in speed to the native methods (i.e., Replace Array Subset and In Place Element Structure). I actually have a scenario where your MoveBlock method might be faster. Using the primitives you cannot replace a portion of a row (which is actually what I want to do). This should be a lightning fast operation but I have to either do it item by item or index out the row first, replace a portion of it and then replace the 2D array. My code might be sped up a bit with an In Place structure, I have not yet tried this. Quote Link to comment
Neil Pate Posted May 12, 2021 Author Report Share Posted May 12, 2021 Method 3 using MoveBlock seems the fastest when you want to replace without starting at zero Quote Link to comment
mcduff Posted May 12, 2021 Report Share Posted May 12, 2021 3 hours ago, Neil Pate said: I actually have a scenario where your MoveBlock method might be faster. Using the primitives you cannot replace a portion of a row (which is actually what I want to do). This should be a lightning fast operation but I have to either do it item by item or index out the row first, replace a portion of it and then replace the 2D array. Probably slower than your method, but it is possible using primitives, and it is quite messy also. See below. Quote Link to comment
Neil Pate Posted May 13, 2021 Author Report Share Posted May 13, 2021 In another plot twist it looks like my original naive method of just doing a for loop is actually quicker than the MoveBlock. I do not really understand this but am going to leave it here for now. Quote Link to comment
dadreamer Posted May 13, 2021 Report Share Posted May 13, 2021 Only when I disable the wrapper generation on the CLFN, I see some small performance gain in MoveBlock against Replace Array Subset: So, in all other use-cases the native nodes do their job just fine and they're much simplier to use (and more safe also). That is just a PoC method to show, that the work with arrays could be done "traditional way" in LabVIEW too as in text-based languages. I even suppose, Replace Array Subset and In Place Element Structure were both optimised/tweaked in some ways to behave better even in a dumb memory copying. Quote Link to comment
Neil Pate Posted May 13, 2021 Author Report Share Posted May 13, 2021 2 hours ago, dadreamer said: Only when I disable the wrapper generation on the CLFN, I see some small performance gain in MoveBlock against Replace Array Subset: So, in all other use-cases the native nodes do their job just fine and they're much simplier to use (and more safe also). That is just a PoC method to show, that the work with arrays could be done "traditional way" in LabVIEW too as in text-based languages. I even suppose, Replace Array Subset and In Place Element Structure were both optimised/tweaked in some ways to behave better even in a dumb memory copying. Sure, but I am surprised that looping over an array doing individual array element replaces is quicker than doing a single MoveBlock! Seems suspicious... Quote Link to comment
dadreamer Posted May 13, 2021 Report Share Posted May 13, 2021 (edited) I did a test like yours with For Loop and MoveBlock is a bit faster here. I'm getting 0,03 ms for RAS and 0,01 ms for MB. I took Initialize Array on MB diagram out of the Sequence, because it's just an extra operation. Also make sure you are not timing and filling the output indicator simultaneously, because the latter vastly impacts the measurements. Edited May 13, 2021 by dadreamer Quote Link to comment
Neil Pate Posted May 13, 2021 Author Report Share Posted May 13, 2021 1 hour ago, dadreamer said: I did a test like yours with For Loop and MoveBlock is a bit faster here. I'm getting 0,03 ms for RAS and 0,01 ms for MB. I took Initialize Array on MB diagram out of the Sequence, because it's just an extra operation. Also make sure you are not timing and filling the output indicator simultaneously, because the latter vastly impacts the measurements. It really makes sense to me to have the MoveBlock be the fastest when replacing a row (or subset of a row). I wonder if the difference is also more exteme as the size of the replacement changes? In other words replacing a section 1M elements long is probably much slower when doing it element by element compared to a single MoveBlock call. Quote Link to comment
mcduff Posted May 13, 2021 Report Share Posted May 13, 2021 The following will replace a row or column subset or complete row or column of a 2D array using native functions and no loops or IPEs. If your subset array is 1D all you need to do is reshape it before a replace operation. ReplaceRowColumnSubset.vi Quote Link to comment
dadreamer Posted May 13, 2021 Report Share Posted May 13, 2021 3 hours ago, Neil Pate said: I wonder if the difference is also more exteme as the size of the replacement changes? In other words replacing a section 1M elements long is probably much slower when doing it element by element compared to a single MoveBlock call. It doesn't seem so. For a row of 1048576 bytes it takes ~4 ms for RAS and ~3 ms for MB. Not a huge difference. Quote Link to comment
Phillip Brooks Posted May 13, 2021 Report Share Posted May 13, 2021 What is the overhead of using Transpose 2D array? https://zone.ni.com/reference/en-XX/help/371361R-01/glang/transpose_2d_array/ Might transpose -> replace -> transpose be an option? Quote Link to comment
Neil Pate Posted May 13, 2021 Author Report Share Posted May 13, 2021 I tried with a longer row replacement, 6000 elements, and the MoveBlock technique starts to become marginally faster. I am going to stick with the simple replace an element at a time method. Quote Link to comment
Rolf Kalbermatter Posted May 16, 2021 Report Share Posted May 16, 2021 On 5/13/2021 at 8:36 PM, Phillip Brooks said: What is the overhead of using Transpose 2D array? https://zone.ni.com/reference/en-XX/help/371361R-01/glang/transpose_2d_array/ Might transpose -> replace -> transpose be an option? Not likely. The efficiency in the Transpose function comes from the fact that LabVIEW really creates something that is called a sub array. This is not a real array but a data structure that contains flags, offset, stride and similar attributes and a pointer to the original array data. Many functions in LabVIEW are able to operate on both arrays and sub arrays. A transposed array simply stores the fact that the array data is actually transposed in the flags and then any function that sees it knows to exchange the row and column value in the original array. If a function doesn't support the sub array flavor it simply calls a function that converts the sub array into a real array, eventually imposing the penalty of the transpose operation anyhow, but many functions can simply work with such sub arrays directly. A graph for instance has the ability to transpose the 2D array data already, so if it receives a transposed sub array it simply inverts the transpose setting of the graph for this array data. For the indexing into the array the fact that the array is transposed should not really make a big difference as the real data is still in the original order (if it wasn't, the whole operation would not only use double the memory but be significantly slower as shuffling the data around is taking some performance). Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.