Speed of wave assignments using wave reference waves

I've found that when I'm using a wave reference wave, my code actually runs faster if I declare each wave I want to use as it's own wave object before operating on it:

Wave myWave = waveRefWave[0]
... = myWave * x

as opposed to just operating directly on the indexed wave reference wave:

... = waveRefWave[0] * x

In this test function, I make two 3D waves that are just added together into an output wave. The first loop does the extra wave assignment step, and is always a decent bit faster than the second loop, which operates directly on the wave reference wave. This doesn't make a lot of sense to me, but I might just misunderstand something about wave reference waves that goes on under the hood. Thoughts?

Function testFunc()
    //Make two 3D waves and a wave reference wave
    Make/O/N=(500,500,200) root:wave0,root:wave1
    Wave/WAVE waveRef = ListToWaveRefWave("root:wave0;root:wave1;")
   
    //Make the output wave
    Make/O/N=(500,500,200) root:outputWave
    Wave outWave = root:outputWave
   
   
    //Run the loop WITH a separate wave assignment step
    Variable ref = StartMSTimer
    Variable i = 0
    Do
        Wave theWave = waveRef[i]
        Multithread outWave += theWave
       
        i += 1
    While(i < 2)
    print "Assigned:",StopMSTimer(ref)/(1e6),"s"
   
   
    //Run the loop WITHOUT the separate wave assignment step
    ref = StartMSTimer
    i = 0
    Do
        Multithread outWave += waveRef[i]
       
        i += 1
    While(i < 2)
    print "Not assigned:",StopMSTimer(ref)/(1e6),"s"
   
End

 

If you write something like MyWave[] = waveRefWave[0] * x I assume the wave declaration is done over and over again for each point of MyWave

My tests with Igor 8.04 on Windows, using a machine with an 8 core/16 thread processor, show no consistent difference between the two:

•testfunc()
  Assigned:  0.500324  s
  Not assigned:  0.477222  s
•testfunc()
  Assigned:  0.453647  s
  Not assigned:  0.516939  s
•testfunc()
  Assigned:  0.481404  s
  Not assigned:  0.483658  s

 

In reply to by thomas_braun

@Thomas, yes just two entries for the purposes of testing this out. It's about 170 ms faster for me on this code, so about 11%. It seems to be constant though-- if I take out the multithreading, 'Not assign' is about the same amount slower than 'Assign', even though the overall runtime is much slower. And I hadn't seen that before, but that's very useful thank you!

OK, I see the problem, my original unassigned loop wasn't doing what I thought and may just be copying the wave reference itself into all the rows/cols/layers of the output wave. Looks like I do need to explicitly declare each wave reference in the wave ref wave before using it. 

In reply to by Ben Murphy-Baum

Ben Murphy-Baum wrote:

OK, I see the problem, my original unassigned loop wasn't doing what I thought and may just be copying the wave reference itself into all the rows/cols/layers of the output wave. Looks like I do need to explicitly declare each wave reference in the wave ref wave before using it. 

This seems like a bug to me. I'll report this to the author of that code.

@aclight Could you post here once that is resolved? I'd like to have a look if and how that influences my code.

In reply to by thomas_braun

thomas_braun wrote:

@aclight Could you post here once that is resolved? I'd like to have a look if and how that influences my code.

Larry has changed Igor 9 so that this gives a compile error on the dd += ww[i] line:

Function test()
    Make/O wave0 = 1, wave1= 2
    Make/O ddd = 0
    Make/O/N=2/WAVE ww
    ww[0]=wave0
    ww[1]=wave1
   
    Variable i = 0
    Do
        ddd += ww[i]
        i++
   
    While (i<2)

End

 

Instead, you would need to write the loop like this:

    Do
        WAVE theWave = ww[i]
        ddd += theWave
        i++
   
    While (i<2)

 

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More