From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Correct way to simultaneously call by reference from a preallocated clone pool

Solved!
Go to solution

Hello everybody,

 

I'm rewriting a code done when I was even more noob in labview than I'm right now. I had to make Pt by Pt operations in a large array of variables. This operations required to know the status of the variable in the previous iterations, so I needed a preallocated clone for each variable. In that moment I saw only two opions: 1) index all the array, place one reentrant subVI for each variable and build the VI again, which is a pain with no scalability and 2) call by reference inside a for loop.

 

Then, in the initialization code, I preallocated the needed number of clones with "Open VI Reference Function", built an array with them and forward it to use it when needed. The problem arrived when I had to choose the flags. I didn't know anything about call VI from references, and the time wasn't playing in my favour. Flag 0x08 and 0x40 seemed very similar for me, and I chose the 0x40 because the descrition from LV help convinced me more because it spoke about parallel for loops. But, the flag 0x40 needs the 0x80 or 0x100 if the VI is preallocated reentrant, and this flags are for asynchronous calls. I chose the 0x100 one, but I didn't want to run them asyncronally, only with the CBR node.

 

So, I have searched for more info: https://forums.ni.com/t5/LabVIEW/Preallocated-Reentrant-VI-within-Parallelized-For-Loop/td-p/3080639...

 

Some speak that 0x08 has more overhead, and others (nathand) that 0x08 returns a preollocated clone reference (that's what I want) while 0x40 returns a "shared clone reference". The fact is that the code has been working correctly since now, but if nathand is right I was doing something really weird here, "preallocating" at initialization an array of shared clone references.

 

Also I have been trying the last days to improve the timming in the code by converting the for loops into parallel loops, without any results. Maybe this is from an incorrect flag setup.

 

To finish, an aside question. Simple VI's, like integration of filter pt by pt, should be CBR in a parallel loop? Or the overhead would be higher than the increased performance? In what order of magnitude is the parallel overhead?

 

Thank you for your time. Best regards,

 

 

EMCCi

0 Kudos
Message 1 of 4
(2,153 Views)

I regret to say that your post leaves me confused.  I have no clear idea of what you want to do (now), and thus am not sure what suggestions (if any) to make.  You seem to be overly concerned with "performance" (also not clearly defined, but I'm assuming you mean "speed of processing"), rather than finding an algorithm and implementation that optimally "fits the problem".  After all, an algorithm that is extremely fast but poorly related to the statement of the problem is pretty useless (e.g. "Generate a Random number" -- very fast, but unlikely to be an acceptable "estimate of the mean of my data").

 

Why don't you describe what you are trying to do, the nature of the data or other inputs, the nature of the question you are asking, and any other important considerations.  Sometimes a "divide and conquer" algorithm is efficient, sometimes a recursive algorithm is efficient, sometimes not.

 

Bob Schor

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

Ok, I have probably explained badly.

 

Long history short: What is the correct flag?

image.png

Long history long: One year and a half ago I had to make an application that receives data from remote sytems on machines, process it, storages it and shows it on web. But, first of all an clarification, I'm not a programmer and I didn't know anything about labview, databases and web. I'm a reconverted mechanical engineer because the job had to be done and I was disposed and wanted to learn it. I have done some NI courses that helped me a lot, but anyways I had some troubles during the developement of the code (as you can imagine) and also that's the reason because sometimes it seems that I make silly questions. (So, any help is appreciated)

 

Returning to the question itself, we receive each second a 2D data array for each machine. One dimension of the array is the # of variables (50-100) amd the other one is the aquisition frequency (1-10k). This raw data we storage them in a DB and we process it (filters, integrals, histograms, power spectrum, averaged buffers for long time chronographs...) and we do this processment Pt by Pt because we receive a data packet every second and we want to display the data in real time. Also we storage the raw data instead the processed data because of this way, if we have done some error in the processement code or if we want to extend it (like now), we could redo all the processement again and get the new processed data. That's the reason because I'm concerned about timming, because I have to reprocess 1 year of data, and time don't play in our favour again.

 

Please, if more information is needed or something isn't clear let me know,

 

 

EMCCi

0 Kudos
Message 3 of 4
(2,050 Views)
Solution
Accepted by topic author EMCCi

The correct flag is 0x08.  (This assumes that you're calling a processing function that returns its output pretty much immediately.)   Those other flags are for cases where you're launching a long-running asynchronous process.

 

I've been in a couple of related threads, and here's the code I ended up with for a similar situation.

 

In another later thread, I made some progress on the complaint I still had about wanting to use parallelized For Loops to do this processing.  I never brought the two things together because the original code was released, working fine, and not in need of the potential performance improvement from parallelization.

 

The main thing I'd advise is to look at the code in my first link carefully.  I was explicitly careful to package the *opening* of the VI refs in code that would only run 1 time on first call and thereafter retain those open refs in a shift register for future usage.   I didn't open and close the refs every time I needed to iterate through the calls to the processing function.

    Somewhat awkwardly, that led to the need to pass the open refs out as output values so that I could close them when it was time for the whole app to stop.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 4 of 4
(2,032 Views)