MatrixOp speed issue with SetRow
I am trying to speed up a function that includes a for-loop that stores a 1D wave in a certain row of a 2D wave. The original code used wave assignments (i.e. matrix[0][] = wave[q]). This worked fine, but I figured I could speed it up using MatrixOp. However, when I replaced that line with MatrixOp, using the SetRow option, it was about 100 times slower.
I wrote some code to demonstrate this problem. In this code, I first compared methods for pulling a row out of a 2D wave and found that, as expected, MatrixOp is faster. Then I compared methods for inserting a row into a 2D wave and found MatrixOp was much slower.
Variable vStartTimer, vStopTimer, iDex
Make/O/N=(2000,2048) mMatrix = p + sqrt(q)
Make/O/N=(1,2048) mSubMatrix
//First, pull each row out of mMatrix and store in mSubMatrix
Printf "\rPart I: pull out a row\r"
//Using wave assignements
vStartTimer = StartMSTimer
For(iDex = 0; iDex < 2000; iDex += 1)
mSubMatrix = mMatrix[iDex][q]
EndFor
vStopTimer = StopMSTimer(vStartTimer)
Printf "Time = %g sec (using wave assignments)\r", vStopTimer / 1000000
//Using MatrixOp
vStartTimer = StartMSTimer
For(iDex = 0; iDex < 2000; iDex += 1)
MatrixOp/O mSubMatrix = Row(mMatrix,iDex)
EndFor
vStopTimer = StopMSTimer(vStartTimer)
Printf "Time = %g sec (using MatrixOp)\r", vStopTimer / 1000000
//Second, insert mSubMatrix into mMatrix for each row
Printf "\rPart II: insert a row\r"
//Using wave assignemtns
vStartTimer = StartMSTimer
For(iDex = 0; iDex < 2000; iDex += 1)
mSubMatrix = iDex + sqrt(q)
mMatrix[iDex][] = mSubMatrix[0][q]
EndFor
vStopTimer = StopMSTimer(vStartTimer)
Printf "Time = %g sec (using wave assignments)\r", vStopTimer / 1000000
//Using MatrixOp
vStartTimer = StartMSTimer
For(iDex = 0; iDex < 2000; iDex += 1)
mSubMatrix = iDex + sqrt(q)
MatrixOp/O mMatrix = SetRow(mMatrix,iDex, mSubMatrix)
EndFor
vStopTimer = StopMSTimer(vStartTimer)
Printf "Time = %g sec (using MatrixOp)\r", vStopTimer / 1000000
End
The result I get is:
•myFunction()
Part I: pull out a row
Time = 0.182665 sec (using wave assignments)
Time = 0.110626 sec (using MatrixOp)
Part II: insert a row
Time = 0.287957 sec (using wave assignments)
Time = 38.3542 sec (using MatrixOp)
What am I missing here? Is MatrixOp slower than wave assignments for some functions?
I am using Igor 7.0.8.1 with Windows 10, but I also had a colleague try it on Igor 8 with a Mac and he got a similar result.
Thanks for any advice you've got!
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
Almost all of the time spent in MatrixOp in this example is copying the data. Unlike with the wave assignment statement, MatrixOp doesn't operate directly on the original input wave.
Given a sufficient number of processor cores, there are many cases where a MultiThread wave assignment statement can significantly outperform MatrixOp. But of course there are many cases, particularly with complicated expressions, where MatrixOp is the best approach.
February 21, 2020 at 05:21 am - Permalink
I think that the main part that you are missing is the optimal usage of MatrixOP. In this case, you want to eliminate the loop completely and you will find significant speed enhancement:
MatrixOp/O mMatrix=indexRows(mMatrix)+sqrt(indexCols(mMatrix))
February 21, 2020 at 02:03 pm - Permalink
Ok, thanks, that makes more sense now!
February 26, 2020 at 08:03 am - Permalink