LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Which is faster? Fmt/Scan or Advanced Analysis Library

I want to extract (double) array data from a large array into separate arrays for processing in a loop while still acquiring data off a daq card.

 

For those operations that are suitably used with Fmt and Scan, would these be better / faster than using the analysis library functions?

 

For example, which of the following would be the better choice for moving an array subset of 100 elements starting at element 200 ?

 

count = 100;

i = 2;

====================================================

   Subset1D (InBuffer, BufferSize, i*count, count, OutBuffer);

 

OR

 

  Fmt(OutBuffer,   "%*f<%*f[i*]", count, count, i*count, InBuffer);

====================================================

0 Kudos
Message 1 of 4
(3,607 Views)

Of course, you can also use memcpy.

 

Frankly, it never even occurred to me to use a function for this. I would automatically just use a for loop, taking care to ensure that the only arithmetic performed inside the loop was simple increments.

 

I expect you will get different speed results depending upon what level of optimization or run-time bounds checking you have enabled. I think LabWindows always does some parameter bounds checks when a library function is called, but not on each cycle of the loop.

 

So I suspect that an explicit for loop will be fastest when you have all the optimisations enabled, and no run-time bounds checking, because there is no function call overhead. From experience, I expect it to slow down considerably when it has to do bounds checks on every array index on every iteration. The call to memcpy or Subset1D will be faster with bounds checking, because you only have the parameters checked when the library function is called.

 

I would expect Fmt to be slowest, simply because it is otherwise such a powerful function, and using it to move data from one place to another does not use the full capabilities of the function.

 

I am fully open to being wrong, and would be most interested to hear of your results.

 

 

0 Kudos
Message 2 of 4
(3,585 Views)

In a case like this I would rather focus on error checking and execution safety instead of execution speed. Let me explain.

If parameters evaluated at runtime give incorrect array bounds (e.g. index + lenght are greater than array lenght), SubSet1D gracefully returns an analysis error code which can be decoded easily.

In the same situation, CVI raises a "Attempt to read beyond end of array" or similar popup message, which is definitely harder to trap. Fmt function returns -2, which is an undocumented return value but being <0 sounds like an error, but GetFmtIOError returns 0 (no error). That error message is really a protection error which I don't know how to get programmatically; furthermore you can hide the popup only by explicitly calling SetBreakOnProtectionErrors, while if you forget it the program is halted waiting for operator's ACK.

That is to say: I definitely vote for SubSet1D or Copy1D or similar safe function.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 4
(3,576 Views)

So I finally wrote a quick piece of code to see who would with the race dumping an integer buffer from one large array to another to answer the question, which is faster, a regular for loop or the NI Fmt function.

 

For 2E9 operations on my 3.4 GHz Optiplex 7010, a regular for loop took 98 seconds. Using the Fmt function with the repeat parameter took 343 seconds for the same count, so the for loop is 3.5 times faster.

 

I know speed wasn't the original intent of the Fmt function, but it's just so nicely concise, easy to apply and powerful for many simple swaps. Too bad it's so slow, but I understand.

 

// After putting values in the large array Buffer[]...

for (j=0; j<10; j++) { for (i=0; i<200000000; i++) ForLoopBuffer[i] = Buffer[i]; } for (j=0; j<10; j++) { Fmt (FmtBuffer, "%*i<%*i", 200000000, 200000000, Buffer); }

 

0 Kudos
Message 4 of 4
(2,798 Views)