02-15-2015 02:41 PM
Hi all,
For background: I am wiritng a DAQ VI with a producer consumer model, strongly based on the Continuous Acquisition and Logging VI.
I am writing the acquired data to a buffer. When the buffer is full, I want to write that data to a file -- in other words, tell the "logging" loop to start writitng.
I would like to know the best way to do this. Right now I am doing the following thing: polling for a full buffer, and then if full, enqueuing a command for the logging loop to start writing the data to file.
02-15-2015 03:08 PM
Why does the logging loop need to be told anything? It has access to the buffer, right? Why can't it decide on its own that it's time to start saving data?
Mike...
02-15-2015 03:18 PM
02-15-2015 03:50 PM
02-15-2015 10:10 PM
So should one poll for a full buffer before writing to file, then? Or is there a better way? I feel like polling for anything is generally inelegant.
02-16-2015 02:50 AM
The point is that, your OS does buffered file IO. Even if you are writing to your file at every iteration of a while loop (lets say at 1 Hz), the OS does not write in real that often: OS writes to your file in chuncks. So I would not worry about buffering. Just put your data into a Queue, and at the consumer loop write to file. What is the DAQ rate? If you do fast acquisition, you might want to have a look how to use DAQmx TDMS operations, which is very fast. Either the case, you do not need to explicitly handle buffering...
02-16-2015 07:48 AM
A little more context would be nice here. What file format are you using? Where is the data coming from? Where/what is this buffer you are referring to?
02-16-2015 09:00 AM - edited 02-16-2015 09:03 AM
Using DAQmx built-in logging is probably better. If that doesn't fit, you're doing premature optimization. You only need to focus on write size if you need crazy high performance and then you start having to worry about buffering and the like. Since labview will buffer for you and the os will buffer for you, you can just leave it be until you've identified that loop as the bottleneck.
Also, this is a peeve of mine so I'm going to call it out specifically:
"I am writing the acquired data to a buffer. When the buffer is full, I want to write that data to a file -- in other words, tell the "logging" loop to start writitng."
The logging loop should know, itself, when to log. After all, it only has that one job. Is that job really so hard? It just sits there, waits for data, and shoves it in a file. 🙂
My point is, *if* your loop needs buffering to hit the write-to-disk performance you need, that buffering is the responsibility of the logger loop not the producer loop. That way the producer has just one job -- producing -- and the logger has just one job -- logging. Any other configuration can and will lead to suffering, eventually.
So to answer your question rather than giving the super obnoxious "don't optimize" statement above, I would say you leave your producer just writing to the queue. On the receiving side you have an allocated array of data and a counter. Every time you receive a packet from the producer you replace some subset of your buffer array and increment your counter. When the counter reaches N, reset the counter and write your data to disk. This keeps everything event-based (reading from the queue) and also eliminates the pesky problem of having the producer doing the logger's job.
02-16-2015 10:07 AM
@AlecSt wrote:
Hi all,
I am writing the acquired data to a buffer. When the buffer is full, I want to write that data to a file -- in other words, tell the "logging" loop to start writitng.
I would like to know the best way to do this. Right now I am doing the following thing: polling for a full buffer, and then if full, enqueuing a command for the logging loop to start writing the data to file.
So, assuming the buffer is a queue or AE in it's own consumer state, it can queue a write-command to the consumer with the data and clear its buffer.
/Y
02-16-2015 12:08 PM