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: 

Reg : Is there any alternative for Queues ?


@Mark_Yedinak wrote:

...avoid processing the queue one element at a time. We create a simple state machine that is time based and when the timer expires, we flush the queue (flushing the queues returns an array of the queued elements) and process all of the elements at one time. ...


 

Not to pick a fight but you got me thinking...

 

I have done that as well but rather than flushing, I have checked the number of elements waiting in the queue and if greater than zero, invoke a For loop to iterate through each of the elements in the queue ONE at a TIME.

 

That approach is based on the theory (only AQ really knows) that when an element is queued-up the pointer ( I know!  probably a handle or what-not) to the buffer holding the new element is what gets transferred to the Dequeue such that Queues can operate "in-place" with only the pointer moving and not the data.

 

If on the other hand we flush the queue, it seems that all of elements in the queue have to be moved to the buffer that the Flush queue returns.

 

Just talking alternatives since "alternatives" is the name of this thread.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 11 of 18
(607 Views)

@Ben wrote:

@Mark_Yedinak wrote:

...avoid processing the queue one element at a time. We create a simple state machine that is time based and when the timer expires, we flush the queue (flushing the queues returns an array of the queued elements) and process all of the elements at one time. ...


 

Not to pick a fight but you got me thinking...

 

I have done that as well but rather than flushing, I have checked the number of elements waiting in the queue and if greater than zero, invoke a For loop to iterate through each of the elements in the queue ONE at a TIME.

 

That approach is based on the theory (only AQ really knows) that when an element is queued-up the pointer ( I know!  probably a handle or what-not) to the buffer holding the new element is what gets transferred to the Dequeue such that Queues can operate "in-place" with only the pointer moving and not the data.

 

If on the other hand we flush the queue, it seems that all of elements in the queue have to be moved to the buffer that the Flush queue returns.

 

Just talking alternatives since "alternatives" is the name of this thread.

 

Ben


You raise a valid point Ben.  In the cases that I have done this the data size was actually not that large so I hadn't really consider the issue of the data copy. We had found with our experiments that the flush was faster than using a FOR loop. This may not hold true though if the data size is quite large. 



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 12 of 18
(597 Views)

@Mark_Yedinak wrote:

...You raise a valid point Ben.  In the cases that I have done this the data size was actually not that large so I hadn't really consider the issue of the data copy. We had found with our experiments that the flush was faster than using a FOR loop. This may not hold true though if the data size is quite large. 

I had the same thought after I posted!

 

So "it depends".

 

Thank you for being a  sounding board!

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 13 of 18
(592 Views)

@Ben wrote:

@Mark_Yedinak wrote:

...avoid processing the queue one element at a time. We create a simple state machine that is time based and when the timer expires, we flush the queue (flushing the queues returns an array of the queued elements) and process all of the elements at one time. ...


 

Not to pick a fight but you got me thinking...

 

I have done that as well but rather than flushing, I have checked the number of elements waiting in the queue and if greater than zero, invoke a For loop to iterate through each of the elements in the queue ONE at a TIME.


I the past, I have skipped the waiting and just used a FOR loop with a Dequeue in it.  So I can get a maximum of, for example 10 elements, but on a timeout (100ms sticks in my mind), just process what I have.  This was after LabVIEW 8.6, which introduced the conditional terminal to the FOR.  It was actually quite simple and I could always adjust the timeout if I needed a faster reaction.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 14 of 18
(567 Views)

Why would there have to be a full (deep) copy of the queue elements in the case of a flush? Sure if your queue element is all consisting of a cluster of simple scalar then yes there might be a copy involved as the Flush Queue node returns an array of queue elements, but if that is the case you are making yourself busy over a very little effect here. Clusters will hardly contain thousends of scalar elements. That would be a true software maintenance nightmare! And for a few dozen scalars you would need a queue with million of elements in there to impose a significant overhead for copying them into the flushed output array and even then you do this Flush hopefully not every few seconds or you have very different problems to tackle first.

 

More likely your queue element will consist of a cluster with a few elements in there that might be scalar and others that might be substantial arrays or strings. No need for the Flush function to copy those embedded arrays too as it will have to delete the original right after anyhow. So it rather does at worst a shallow copy of the top level memory layout for the queue element into the flushed array and then the ownership of those (potentially huge) arrays and strings will be simply passed to whoever processes the flushed array. Nothing fundamentally different to retrieving each queue element individually. In fact it might be usually faster since each Deque call has to verify the queue refnum again and dereference the actual queue that this refnum refers too. That costs some time too and that overhead is likely just as big as the shallow copy of the top level memory layout for a queue element unless your queue datatype is truely huge and totally flat (cotaining only scalars).

Rolf Kalbermatter
My Blog
0 Kudos
Message 15 of 18
(551 Views)

@rolfk wrote:

Why would there have to be a full (deep) copy of the queue elements in the case of a flush? Sure if your queue element is all consisting of a cluster of simple scalar then yes there might be a copy involved as the Flush Queue node returns an array of queue elements, ...


 

If I am queue-ing up a 2d-Array of scalars, the flush queue would return an array of clusters of 2d arrays.

 

Wouldn't there be a data copy involved in that case?

 

Spoiler

 

While it has been a few years and I don't have that hardware ...

 

I was acquiring from a HSDIO PXIe board to sample from a digital microphone. I had to get it out of the hardware buffer as quickly as possible to keep the acquisition from over-flowing.

 

That data got passed via a queue to an initial processing loop (the code looked like it was FPGA code) that separated the left and right channels of a microphone based on a rising or falling clock.

 

Those two binary bit streams were then passed to two more queues that did the PDM conversion down into the audio range.

 

The PXIe application was able to keep up as long as the HSDIO sampling rate was 400Mhz. At 800 Mhz... my queues were backing up because I simply could not process the binary stream fast enough.

 

I dearly wanted to post that code as a challenge to se if people could double my performance, but sadly "it was against the rules".

 

 

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 16 of 18
(533 Views)

Well the queue element would be a cluster with an array handle to a 2D array. That would copy exactly 4 (8 on 64 bit LabVIEW) bytes per queue element, namely the handle pointer. The array itself is stored in its own memory block and referenced by the handle and whoever receives that handle is the owner of it.

Rolf Kalbermatter
My Blog
Message 17 of 18
(523 Views)

@Ben wrote:

@Mark_Yedinak wrote:

...You raise a valid point Ben.  In the cases that I have done this the data size was actually not that large so I hadn't really consider the issue of the data copy. We had found with our experiments that the flush was faster than using a FOR loop. This may not hold true though if the data size is quite large. 

I had the same thought after I posted!

 

So "Depends".wasn't that Dole's answer to "Boxers or Briefs?"

 

Thank you for being a  sounding board!

 

Ben


You ALWAYS have an alternative to Queues..They won't often be faster!  In fact, I bet the other methods will not be faster..


"Should be" isn't "Is" -Jay
0 Kudos
Message 18 of 18
(504 Views)