05-20-2009 04:03 AM
Yes there has been a lot said and left unsaid about LabVIEW performance in the past - but I have to ask the following:
Is it possible to have two seperate while loops act on the same data without making copies?
Say I have a 1GB array of doubles which I have wired to a shift register on one loop. With a little bit of effort (by using in-place and chasing the dots a bit) it would be possible to operate on that data inside that loop without making copies.
But what if I need to also access that same array in a different loop (which is running at a different rate). I basically need two loops' shift registers to point to the same data. At the moment the only way I can manage this is to use DLL calls which destroys dataflow but al least makes no copies. It also means I cannot use LabVIEW code but have to resort to C coding.
Data corruption is no issue as the two loops, at any instant, operate in different locations of the array.
Any smart ideas that will work?
05-20-2009 05:24 AM
Hi AnthonV,
A Functional Global approach might suit your needs. This will allow you to keep you data in a shift register, but access/modify parts of the data from other VIs or loops.
Another option is to use a single element queue to store the array to achieve a similar result.
Both these options and more techniques are located at
http://zone.ni.com/devzone/cda/tut/p/id/3625#toc0
Hope that helps
05-20-2009 06:49 AM
drclaw wrote:Hi AnthonV,
A Functional Global approach might suit your needs. This will allow you to keep you data in a shift register, but access/modify parts of the data from other VIs or loops.
Another option is to use a single element queue to store the array to achieve a similar result.
Both these options and more techniques are located at
http://zone.ni.com/devzone/cda/tut/p/id/3625#toc0
Hope that helps
Good suggestion. Functional Globals also go by the name "Action Engine" as I discuss in this Nugget on Action Engines.
Put all of your number crunching code inside appropriately named Actions of the AE and that way all of the work CAN be done "in-place".
Have fun!
Ben
05-20-2009 08:13 AM
Thanks for these ideas guys.
But am I correct in saying that the functional global or 'action engine' will not work for me if the one loop's period is shorter than the time taken to process in the other loop. This means that while the one loop is doing an 'action' that takes say 100ms to complete, the other loop which is running at say a 1ms period is going to be denied access to the functional global for 100 iterations?
What is key here is that I need concurrent access to the array.
(BTW this is an RT application running on a DELL 4 core desktop PC).
05-20-2009 08:19 AM
05-20-2009 08:41 AM
Unfortunately no. Think of the array as a circular buffer where the one loop is dumping data into the array and performing some algorithm that might take 100ms to complete on a block of data, while another loop is trawling through the buffer extracting data and performing some other process which has to run every 1ms. So they never operate on the same part of the buffer simultaniously but they both operate on the whole buffer over a long enough period of time...
Does this make sense?
05-20-2009 08:56 AM
AnthonV wrote:Unfortunately no. Think of the array as a circular buffer where the one loop is dumping data into the array and performing some algorithm that might take 100ms to complete on a block of data, while another loop is trawling through the buffer extracting data and performing some other process which has to run every 1ms. So they never operate on the same part of the buffer simultaniously but they both operate on the whole buffer over a long enough period of time...
Does this make sense?
I see. In the past I've used a binary file for with two open file references, one for writing, the other for reading (Read-Only). The two can operate on the file simultaneously without problem, as long as your hard drive can write and read the data fast enough.
Otherwise, the above mentioned Action Engines should do fine. If there is a functional global used for storing the data, and a couple of wrap-around subvis that operate on this, then the two oughtn't collide in any way. The loop that takes, for example, 100ms to operate, doesn't need constant "100ms" access rights to the data, right? It should only need to grab/paste a chunk of data in one quick action, the algorithm itself taking the majority of the time. Does that make sense?
05-20-2009 09:21 AM
05-20-2009 09:30 AM
If your FG only provides get and set access to the data, the two loops can then implement the algorithm on small local sets of data (get) and update the main FG buffer (set), running at arbitrary speeds.
In short place the application logic in the loops not in the FG.
Would this suffice for you application?
05-20-2009 12:42 PM
Hmm, I was hoping for something simple but is seems that I will have to make do with a workaround. There is no guarantee that both processes won't require access to the array 100% of the time, so a single access controlled FG is not an option. If I believe my own assumption that the two processes won't be operating on the same section of the array concurrently, the idea of using multiple FG's to segment the array into smaller pieces seems to be the best option so far.
For the record this is still not a very elegant way of doing it, but we have the restrictions related to the Dataflow concept to contend with I suppose.
Personally I think I'll stick with DLL's for now as it makes the code fit the multirate and RT concepts better and it ends up being easier to read and debug. Pity that I'll have to use those 3rd party C++ libraries for the algorithms.
Isn't it possible in LabVIEW FPGA to gain access to another loop's shift registers in some way, I might be mistaken but I recall seeing such a feature when 8.5 or 8.6 was released?