07-27-2010 08:43 AM
I am trying to do buffered CO on a new X-Series board. I slightly modified on of the NI-examples by simply adding a DAQmx-Write into the loop in order to generate an infinite sequence of pulses without regeneration. Basically this works, the only DRAMATIC problem is that this approach consumes 50% CPU on my dual-core and 100% if I add a second counter loop which I will need in the final application.
The funny thing is: the 50% load seems totally independent of whether I generate at 1 kS/s or at 3 MS/s !?
Is this a bug or is it a feature 😉 ? What am I doing wrong ? This new feature would be just so convenient for my current application - and for many others too, I guess.
Many thanks in advance for any suggestions
btw. I am using LabView 2009 SP1 and DAQmx 9.0.2f4
07-28-2010 04:36 AM
Damit die CPU-Last nicht so hoch geht und der Prozessor noch Zeit für andere "Aufgaben" hat, fügen Sie bitte in den Schleifen eine Timing-Funktion (z.B. bis zum nächsten Vielfachen von ms warten) ein! Selbst wenn das Timing nur 1ms beträgt, steigt die CPU-Last nicht bis auf 100 % an! Es ist grundsätzlich so, dass Sie Schleifen immer timen sollten, um solche Phänomene zu vermeiden. Damit wird das Problem bei Ihnen auch behoben sein.
Eine andere Anmerkung habe ich noch zu Ihrem VI. Sie verwenden eine While-Schleife, allerdings schreiben Sie immer wieder dieselben Werte innerhalb der Schleife, da Sie diese bereits vor der Schleife (einmal!!!) erzeugen. Es genügt also, wenn Sie das Schreiben auch vor der Schleife platzieren. Eine Abfrage "Task done?" innerhalb der Schleife wäre dann sinnvoll. Sie finden auf der Palette ein passendes DAQmx VI für die Task-done-Funktion.
07-28-2010 04:44 AM
Why not in english here
Thus, the CPU load is not so high and the processor is still time for other "tasks" has, please include the loops in a timing function (for example, wait until next ms multiple of one)! Even if the timing is only 1ms, increases the CPU load to not up to 100%! It is a principle, that you should always timing loops in order to avoid such phenomena. Thus the problem will be resolved with you too.
Another note I still have your VI. You use a while loop, but you always write back the same values within the loop, as this already before the loop (once! Produce!). Therefore it is sufficient if you put the letter even before the loop. A query "task done?" within the loop would be useful. See the range of a suitable DAQmx VI for the task-done feature.
07-28-2010 05:12 AM
I am sorry but inserting a timer VI into the loop does not change anything - the loop is already timed by the DAQmx-Write, which by default only returns after all samples have been written to the hardware. You can easily verify that:
Run the VI that I attached in the original post and even with a simulated device you will notice that the loop counter updates only every second - this is not a loop "running wild".
About the other remark: this VI is just a skeleton - in the final application a Queue will supply fresh data to the loop in every iteration, but there is no point implementing that as long as the CPU-load issue is not solved 😉
Thank you so far
08-01-2010 07:59 AM
I don't have a X-series board or LV 9 so I can't test your code, but I've never known a "DAQmx Write" to provide any kind of CPU relief. It's true that the call to DAQmx Write won't return until the data is written, but the writing only involves putting the data into the PC's RAM. It *doesn't* wait until those pulses are physically generated as hardware signals.
Did you actually *try* putting a delay in the loop? Just as Elmar posted (and muks translated), I too would *expect* your code to consume excessive CPU. Here's a breakdown:
1. CPU is used to write new output pulse specs to the RAM buffer. The status of the "stop" button is likely being checked simultaneously.
2. The call to DAQmx Write.vi returns as soon as these are written to RAM. The CPU continues to be used to test for loop termination.
3. The next loop iteration begins immediately with step 1.
4. After some number of iterations, you will probably produce an error with DAQmx Write due to overfilling the limited-size buffer.
I suspect your 50% CPU utilitzation amounts to 100% of the core to which the loop thread is assigned. How fast does your loop counter increment when you use your real X-series device?
08-05-2010 06:08 AM
thanks for your suggestions - I am sorry I took a little time to respond, I was at the customers site installing (+ invoicing ) the software.
Luckily for this customer a finite generation (just some 10 minutes or so) is good enough and that is what I implemented. Nonetheless the continuous / non-regeneration mode seems a very powerful feature of the X-series and I am looking forward to using it heavily in the future.
There is a bug-fixing request pending at NI in Austin - unfortunately I don't have the CAR number as yet but they did confirm the 100% CPU load is not the intended behavior.
Regarding your doubts as to whether a DAQmx-Write can (or in this case rather "must") be used to time a loop:
Here is an example of an analog generation utilizing just this:
Here is a digital generation:
It is true, there are very few examples to be found for this kind of mode. Maybe that explains why so few people even know about this powerful feature - surprisingly enough even at NI support 😞 Nonetheless the above approach has been working since way back in 2005 or so when they introduced DAQmx and I have been heavily using it ever since. Hopefully NI will provide a similar example for the counters also in the future.
Thanks again for you help
08-05-2010 07:57 AM
I'm glad your immediate problem is resolved. That's an interesting little tidbit about DAQmx Write that I never knew before. I'm curious about *why* and *how* it works.
Let's take a concrete example of 1 kHz output. Suppose your buffer holds 5000 samples and you've written once to fill it initially and then started the output task. Now you enter the loop and call DAQmx Write to write a half-buffer (2500 samples) of data. Here's what I *suspect* might be going on: Since the last write ended at the very end of the buffer, DAQmx's write pointer is pointing to the beginning of the buffer. So it wants to put those 2500 samples in the first half of the buffer. However, it can tell that the samples it would be trying to overwrite have not been output yet. I would have expected that scenario to produce an error. Instead (apparently), DAQmx chooses to wait and write only after the corresponding buffer slots have been output. So if you keep writing 2500 samples, it'll keep having to do this smart waiting, and it should keep returning from those waits at 2.5 second intervals.
Pretty nice, really. And it makes more sense than simply throwing an error like I expected. So one last little thought of something to look for and try. Even though there's a CAR filed on the issue (acknowledging an internal implementation problem), I wonder if there might be a workaround analogous to something I've fiddled with for AI tasks. There's a pair of DAQmx Write properties that let you set the "Wait Mode" to 'sleep' and then set a sleep time in msec. Maybe one of the other modes ('poll', 'yield') is default and the CPU utilization issue can be avoided by explicitly setting the mode to 'sleep'? Here's a little screenshot:
Hope it helps, and thanks for the post back with those links! That's a useful tidbit to know, that DAQmx Write
is smart enough to wait for buffer space rather than throwing an immediate error.
08-05-2010 10:10 AM
the behaviour of the DAQmx-write you described is just what it does - at least for an outside observer like myself. The loop would cycle every 2.5 seconds - I've verified this many a time!
That is a truly interesting bit of information about this "wait mode". Its amazing time and again what one can do with property nodes. I will verify this as soon as I have suitable hardware again in the office ... have sold mine right now
Thanks again for your help
ps. personally I think the LabVIEW suite is really a fantastic piece of software - I wonder when NI will bring their documentation up to the same level of perfection