
FastOp vs. alternatives

thomas_braun
I recently was faced with the easy sounding task of setting an existing wave to zero. And doing it really fast.
I played around a bit and got some, at least for me, surprising results using the following code:
Function doStuff() variable i, timer, numRuns, waveSize numRuns = 10 waveSize = 2^24 timer = startmsTimer for(i = 0; i < numRuns; i += 1) Make/D/FREE/N=(waveSize) data WaveClear data endfor printf "Plain creation: %g\r", stopmstimer(timer)/1e6/numRuns timer = startmsTimer for(i = 0; i < numRuns; i += 1) Make/D/FREE/N=(waveSize) data = 0 WaveClear data endfor printf "Init with value: %g\r", stopmstimer(timer)/1e6/numRuns timer = startmsTimer for(i = 0; i < numRuns; i += 1) Make/D/FREE/N=(waveSize) data FastOp data = 0 WaveClear data endfor printf "FastOp: %g\r", stopmstimer(timer)/1e6/numRuns timer = startmsTimer for(i = 0; i < numRuns; i += 1) Make/D/FREE/N=(waveSize) data data[] = 0 WaveClear data endfor printf "Plain assignment: %g\r", stopmstimer(timer)/1e6/numRuns timer = startmsTimer for(i = 0; i < numRuns; i += 1) Make/D/FREE/N=(waveSize) data // not sure how to set the complete wave just to zero MatrixOP/FREE data = data - data WaveClear data endfor printf "MatrixOP (single thread): %g\r", stopmstimer(timer)/1e6/numRuns timer = startmsTimer for(i = 0; i < numRuns; i += 1) Make/D/FREE/N=(waveSize) data // not sure how to set the complete wave just to zero MatrixOP/FREE/NTHR=0 data = data - data WaveClear data endfor printf "MatrixOP (multithreaded): %g\r", stopmstimer(timer)/1e6/numRuns timer = startmsTimer for(i = 0; i < numRuns; i += 1) Make/D/FREE/N=(waveSize) data Multithread data[] = 0 WaveClear data endfor printf "Multithread assignment: %g\r", stopmstimer(timer)/1e6/numRuns End
On my windows box using IP6 latest I get:
•dostuff()
Plain creation: 0.0398167
Init with value: 0.212837
FastOp: 0.0620453
Plain assignment: 0.268874
MatrixOP (single thread): 0.12646
MatrixOP (multithreaded): 0.12627
Multithread assignment: 0.0722515
Is
FastOp
really the best choice for that?I would have expected that the multithreaded solution is the fastest one.
First MatrixOP: The multithreading in MatrixOP is not going to kick in because you are not working with multiple layers.
FastOP: I suggest that you avoid it.
Multithread is the best approach for this task.
A.G.
WaveMetrics, Inc.
May 11, 2015 at 09:30 am - Permalink
A.G.
WaveMetrics, Inc.
May 12, 2015 at 03:43 pm - Permalink
So I'll stick with
Multithread
for now.Regarding
MatrixOP
you are of course right.And the new MatrixOP functions are nice!
May 13, 2015 at 12:28 pm - Permalink
Here are the results on my Windows machine (64-bit release build of Igor 7):
•doStuff() Plain creation: 0.0446025 Init with value: 0.49112 FastOp: 0.0522403 Plain assignment: 0.491873 MatrixOP (zeroMat): 0.158381 MatrixOP (single thread): 0.167936 Multithread assignment: 0.0947317
WARNING: If you want to run the test yourself using Igor 7, you must download the nightly build dated May 14, 2015 or later. There was a bug in MatrixOP zeroMat prior to May 14, 2015 that could cause a crash when the test code above is executed.
One other note: the Make line in the test block for MatrixOp zeroMat is unnecessary, since zeroMat will create the output wave on its own. Removing that line makes the timing for the MatrixOp zeroMat block:
MatrixOP (zeroMat): 0.113347
I tried using MatrixOP const() as AG suggested but I haven't figured out yet how to get that function to return a wave whose type is double precision floating point.
May 14, 2015 at 06:52 am - Permalink
Note that the following comments apply to IP7.
For example, you can create an int16 output this way:
For DP:
Note that fp64() may not be necessary if the token "someValue" is already DP. For example,
May 14, 2015 at 03:15 pm - Permalink
MatrixOp
const.This gives on my windows box with latest IP7:
•dostuff() Plain creation: 0.0398512 Init with value: 0.305097 FastOp: 0.0432722 Plain assignment: 0.306107 MatrixOP (const): 0.0908975 Multithread assignment: 0.0686955
So MatrixOP is gaining ground, altough FastOP still leads.
May 19, 2015 at 09:59 am - Permalink
1. WaveTransform setZero data
2. WaveTransform /V=0 setConstant data
Oh, and your testing code should remove all "Make" instructions in MatrixOP cases.
A.G.
May 19, 2015 at 01:25 pm - Permalink
What's wrong with FastOp?
May 19, 2015 at 11:25 pm - Permalink
Larry Hutchinson
WaveMetrics
support@WaveMetrics.com
May 20, 2015 at 07:39 am - Permalink
With the updated code:
I now get
•doStuff() Plain creation: 0.037367 Init with value: 0.307956 FastOp: 0.0427034 Plain assignment: 0.306808 MatrixOP (const): 0.0913224 WaveTransform (setZero): 0.0473604 WaveTransform (setConstant): 0.0428477 Multithread assignment: 0.0675981
And so
WaveTransform
andFastOp
are the current winners.May 20, 2015 at 09:20 am - Permalink
On my machine:
FastOp: 0.0385148
WaveTransform setZero: 0.00623636
... and yes, I did not write FastOp :)
May 20, 2015 at 11:26 am - Permalink