LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Erratic FIFO behavior

Solved!
Go to solution

I'm currently experiencing an issue with some data collection FPGA code that has me scratching my head. I'm using a cRIO-9048 to run two external control loops for a servo drive (Position and Speed loops). Normally this data collection code works just fine, but if I enable the Boolean in the diagram I shared (Position Loop.png) called "Const. Speed", the data coming back across the FIFO shifts two index positions, and I don't understand what is causing this. Wondering if anyone has come across anything similar. I'm using LabVIEW 2020 SP1 f1 (LabVIEW FPGA  and Real-Time 20.0.0)

Download All
0 Kudos
Message 1 of 9
(154 Views)

Hi Scott,

 


@ScottR22  wrote:

the data coming back across the FIFO shifts two index positions, and I don't understand what is causing this.


Index shifting when sending interleaved channels via a FIFO is usually caused when:

 

1. A number of elements that is not a multiple of the number of channels is read or flushed from the FIFO.

In your case you have 14 interleaved SGL channels, so you must always read a multiple of 14 from the FIFO.

 

2. The FIFO buffers overflow (either FPGA side and/or RT side) because the FPGA is writing elements too rapidly and the host cannot read fast enough. This is often caused by a too small buffer size configured on the host side or the reading task not executing frequently enough.

 

From what I see, the changing of the boolean "Const. Speed" alone cannot explain what you are experiencing.

To help further, we would need your actual code (VI files), including FPGA and RT code. The whole project is even better to have IOs and FIFOs configurations as well.

 

Regards,

Raphaël.

0 Kudos
Message 2 of 9
(148 Views)

Thank you, I am only reading 14 at a time on the RT side for sure, but your suggestion about buffer size could be possible, I'm currently initializing the buffer to 2M, which I thought was big enough to not overrun. 

 

It's interesting that I haven't seen this behavior except when I enable that Boolean though. This only seems to happen then, and as you can see all it does is basically disable my speed loop output to input a constant value into my position loop.

Download All
0 Kudos
Message 3 of 9
(141 Views)

Thanks, but I was hoping for VI files, screenshots are only a partial representation of the code.

 

From your screenshot "FIFO RT Code" though, I can already see a few problems in your code:

FIFO RT Code.png

1. Accessing user interface elements (indicator terminals, control property nodes, control references) in the same loop as the FIFO reading is quite inefficient. Accessing UI elements requires LabVIEW to internally switch between current and UI threads each time. Your FIFO reading should be a fast, high-priority, robust and efficient task to ensure elements are read fast enough, while your GUI should be managed in a different, of lesser-priority loop.

 

2. Use e.g. a cluster in a shift register in your FIFO reading loop to store parameters (Recording, Test File Name, Quit, Recording Wait, ...), which will be much more efficient than reading front panel controls.

 

3. You are reading from the FIFO only 1 packet (14 elements) at a time. You should definitely check the number of elements available first, then read the biggest multiple of 14 as possible. This way your loop will handle data more efficiently and need to run less frequently.

 

4. You may also want to put the writing to the file in its own independent loop, to ensure data is read even in case of file error.

 

5. Use Queues or RT FIFOs (different from DMA FIFOs!) to communicate between loops, not UI controls.

 

Regards,

Raphaël.

0 Kudos
Message 4 of 9
(114 Views)
Solution
Accepted by topic author ScottR22

@raphschru wrote:

1. Accessing user interface elements (indicator terminals, control property nodes, control references) in the same loop as the FIFO reading is quite inefficient. Accessing UI elements requires LabVIEW to internally switch between current and UI threads each time. Your FIFO reading should be a fast, high-priority, robust and efficient task to ensure elements are read fast enough, while your GUI should be managed in a different, of lesser-priority loop.


Slight clarification is needed here. Getting the front panel control values via a property node is what causes the thread swap and causes the massive slowdown. If the OP just used the terminals, this would be a non-issue.

 


@raphschru wrote:

3. You are reading from the FIFO only 1 packet (14 elements) at a time. You should definitely check the number of elements available first, then read the biggest multiple of 14 as possible. This way your loop will handle data more efficiently and need to run less frequently.

 

4. You may also want to put the writing to the file in its own independent loop, to ensure data is read even in case of file error.


This is likely the biggest slowdown in the loop as the Write Delimited File opens and closes the file each time it is called.

 

Using a Producer/Consumer setup would help, with the idea of the reading of the FIFO is its own loop that can run as fast as possible and using a queue to send that data on to another loop that can do all of the processing and logging.

 

But this should also be combined with using proper file management. The file should be opened/created before the consumer loop, closed after the loop, and then you can write to it as much as you like inside of the loop. Use Array To Spreadsheet String to format the data into a string to write to the text file.


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 5 of 9
(94 Views)

Thank you very much, I'll work towards implementing your suggestions.

0 Kudos
Message 6 of 9
(79 Views)

Can you clarify what you mean with bullet #1, I had an architect tell me once that the most efficient way to access UI controls/indicators is via reference, because they access the same memory space, whereas local variables create new memory locations and are more prone to race conditions when transferring information between loops, have I been misinformed? If I use a cluster to propagate information via shift registers in loops, wouldn't I need to use references or local variables to have current information?

0 Kudos
Message 7 of 9
(61 Views)

@ScottR22 wrote:

Can you clarify what you mean with bullet #1, I had an architect tell me once that the most efficient way to access UI controls/indicators is via reference, because they access the same memory space, whereas local variables create new memory locations and are more prone to race conditions when transferring information between loops, have I been misinformed?


Yes, you have been grossly misinformed. Using references to get values still creates a data copy but does it in a horribly inefficient manner (forced to use the UI thread instead of the data buffer terminals use). Even worse, you do not reduce race conditions from parallel loops because they still get or set their data at random times. I created a presentation ~15 years ago specifically because this was a popular way of "avoiding local variables". It was my #1 pet peeve.

 

In summary: Using Value Property Nodes does not alleviate any issues associated with Local Variables (data copy, race conditions, etc) and is SLOW. And when I say "SLOW", I means 1000s of times slower. Attached is a benchmark I quickly put together. 1 million writes in a FOR loop. Local Variable takes 32ms while the Property Node takes 164s. This is a 5000x increase in time.

 

Addendum: I replaced the property node with the terminal (changed the control to an indicator) and the terminal was, on average, slightly faster than using the local variable. Not enough that I'm going to scream about it. It would take too long to refine the benchmark (I'll leave that for Altenbach). My understanding was that they use the same code path to write the value, so there should be no difference.


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 8 of 9
(53 Views)

Wow, thank you for the information.

0 Kudos
Message 9 of 9
(45 Views)