Unclear on coding structure to optimize fit with Main event loop speed
fltcoils
Current desktop systems with multicore 3ghz CPUs, SATA3 and USB3 are able to process input and deliver output many times faster than 15 years ago. Given that many users are able to work from such modern systems; can there be a way to tailor the loop speed for newer hardware and modern OSes? A setup value in the registry or such that can be altered to allow for a faster loop speed would have some benefit.
My application evolved from analysis of spectral waveform data into a more comprehensive control system which uses the convenient VISA functions to arm and read data from scopes, thus to also acquire the data. Over time this easy and helpful system has shown much utility. There is, of course, a constant goal of increasing capability, and thus acquisition speed.
Reading about feedback control problems (http://www.igorexchange.com/node/2624) I've realize I don't really have a way to understand how IGORs "main control loop speed" affects the way code in the .ipf files is written and executed. If something obvious such as avoiding do/while for/next loops would increase execution speed 100 times it certainly would make users happy.
I can guess a number of possibilities for what main loop speed is/does:
Speed at idle at which IGOR checks for user input
speed at which subroutines are triggered when called
speed at which XOPs are triggered when called
speed of executing individual command lines
speed of do/while for/next loops
Many coding options, subroutines, do/while loops, are written mostly for legibility rather than necessity. If structuring to use subroutines, or do/while for/next loops causes everything to pause and wait for another 20ms main loop to trigger, then I would want to change how I code in certain time critical places.
Any direct information or links would certainly be appreciated.
But Igor has other things it does periodically as well- it runs background tasks, updates the display when you change the data in a wave, and things of that nature. So Igor has a need to run the event loop even when there are no OS events coming in. As you say, we limit the speed of that loop to avoid hogging the CPU. That limit does limit the rate at which background tasks can repeat, but it does not affect the rate at which loops in a user-defined function can run, or the rate at which a user-defined function can be invoked. Igor code runs at the maximum rate possible.
User input is controlled by the OS, and whenever a user-input event occurs, whatever OS call delivers those events will run pretty much as soon as an event occurs.
No.
No, with the exception of background computing. For instance, when you run a background acquisition using NIDAQ Tools MX, the data is transferred to waves or Igor FIFOs with the same loop that controls background tasks. Since the loop doesn't run when a user-defined function is running, we provide the DoXOPIdle command to allow XOPs time when they wouldn't otherwise get idle time to run. That could also be used to make background XOP code run more frequentlly than our main loop permits.
The DoUpdate command will cause background tasks to run, but be careful- it also updates the screen, and that's very time-consuming.
If you copy a bunch of commands and paste them into Igor's command line and press Enter, then the command lines are executed at a rate that is actually a sub-multiple of the 20 loops/second rate that we are discussing. In general, actions that are initiated by the user don't have to be very fast because "in the blink of an eye" is actually pretty slow in computer terms. Naturally, if a command takes a lot of computation, it will not run fast, but that's a different problem. If it's just a person waiting for something to happen, 20/second is pretty fast.
No.
Optimizing code is a large topic, and Igor's compiler isn't smart so you can make a big difference by paying attention to details. But the main event loop speed isn't involved in the speed of execution of a user-defined function.
First- write code that's readable and maintainable. Think about speed only later. Most code doesn't need to be optimized, and it is better to go back and optimize the critical code after you have it all working. But in that critical code:
Loops in Igor code tend to be slow, so any time you write a loop you should think about whether it can be implemented in another way. Write wave assignments in preference to loops.
For most matrix operations MatrixOP is faster than wave assignmentes.
In critical places, like in tight loops, make sure to pre-compute constant expressions. For instance, it's common in a fitting function to multiply a coefficient by a constant. If that happens more than once, move the multiplication outside the expression that uses it and assign it to a variable.
Function call overhead is high in Igor's language. If it's really a speed-critical piece of code, you may want to inline the code of a subroutine function.
The biggest speed-up you can get is to write really speed-critical code in C/C++ in an XOP. The effort of writing an XOP is such that you have to really want the speed in order to justify the time and effort.
But I come back to my warning above- in most cases the improvement in speed isn't worth writing obscure code. Don't optimize code that doesn't make you wait for it.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
May 14, 2012 at 12:31 pm - Permalink
I appreciate your addressing code optimization in IGOR. I'll have to study this to see how I can improve my project. Your response does provide some direction.
May 15, 2012 at 08:32 am - Permalink