11-04-2013 11:42 PM
Hi all,
I have read few pots online regarding the timing control and CPU usage in CVI and labview. I am trying to compare it in my computer since timing is pretty critical in my application. But I don't have real time system so I would like to know how much difference will be by using labview and/or CVI. My testing is pretty simple, start a loop to lopp1000 time in which loop I will pause for 20 millisecond, I try the following labview code
I repeat running this for many times and it will roughly return 20500 millisecond while we expect 20000 millisecond.
Now in CVI, I use the following code
int CVICALLBACK BTNCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
if (event==EVENT_COMMIT)
{
clock_t start = clock();
for (int i=0; i<2000; i++)
{
Sleep(20);
}
clock_t end = clock();
char str[128];
sprintf(str, "time elapsed %.10f", (double)(end-start)/(double)CLOCKS_PER_SEC);
MessagePopup("time elapsed", str);
}
return 0;
}
This code will return about 41.443 seconds elapsed instead of 20seconds!!! I also try to use SyncWait but it doesn't help much
int CVICALLBACK testcb(int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
if (event==EVENT_COMMIT)
{
double mark, interval=20/1000.0;
clock_t start = clock();
for (int i=0; i<2000; i++)
{
mark = Timer();
SyncWait (mark, interval);
}
clock_t end = clock();
char str[128];
sprintf(str, "time elapsed %.10f", (double)(end-start)/(double)CLOCKS_PER_SEC);
MessagePopup("time elapsed", str);
}
return 0;
}
it returns about 42.005 seconds. So why is that? I know it is not possible to control the timing better than millisecond, but why labview will get better result in timing issue but CVI not. How can precisely control timing in CVI (at least the same performance observed in lbaivew)?
11-05-2013 12:19 AM
Maybe it's worth trying the async timer, see here
11-05-2013 01:41 AM
Another hint is to put the Sleep policy to not sleep: the sleep policy is set with Options >> Environment menu item.
Alternatively, the sleep policy can be set programmatically in the portion of code of interest with SetSleepPolicy () command.
This option has a great influence since affects the processor may be interrupted for other tasks; in effect, you have to notice these remarks both in Sleep and SyncWait () help (highlight is mine):
SyncWait: In the following code, SyncWait ensures that each iteration of the loop takes at least three seconds:
Sleep: Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses.
11-05-2013 08:06 AM
@RobertoBozzolo wrote:
Another hint is to put the Sleep policy to not sleep: the sleep policy is set with Options >> Environment menu item.
Alternatively, the sleep policy can be set programmatically in the portion of code of interest with SetSleepPolicy () command.
This option has a great influence since affects the processor may be interrupted for other tasks; in effect, you have to notice these remarks both in Sleep and SyncWait () help (highlight is mine):
SyncWait: In the following code, SyncWait ensures that each iteration of the loop takes at least three seconds:
Sleep: Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses.
Thanks. I try sleeppolicy, but it doesn't help much. It seems that the estimated time is always almost double of the expected one.
11-05-2013 08:07 AM
11-05-2013 08:07 AM
That's strange. Can you post your project so that we can look at it?
11-05-2013 08:12 AM
No, it can be used with regular run-time engine.
You can have a look at the sample samples\toolbox\asyncdem
11-05-2013 08:24 AM
Hello,
I think everyone is missing the problem.
It took me a few seconds to see it as well...
Your CVI code is running the loop 2000 times instead of 1000 times:
for (int i=0; i<2000; i++)
{
Sleep(20);
}
I hope that helps!
Jeff
11-05-2013 09:02 AM - edited 11-05-2013 09:03 AM
@Jeff_P. wrote:
Hello,
I think everyone is missing the problem.
It took me a few seconds to see it as well...
Your CVI code is running the loop 2000 times instead of 1000 times:
for (int i=0; i<2000; i++) { Sleep(20); }
I hope that helps!
Jeff
Thanks Jeff. I admit that it is my mistake ... well actually the very first code I wrote for testing was correct but before I post it, I modify the loop time for testing. Let me restate my question here.
At the very beginning, I am trying to compare how close the timed loop control in labview and CVI by delay a loop (1000) with timer delay of 5 millisecond (not 20). I have my labview code posted as before but just chhanged the timer to 5 millisecond. I got the total time elapsed about 5100 ms (roughly 100 ms more spent)
In CVI, here is the correct code I used
double mark, interval=5/1000.0;
SetSleepPolicy(VAL_SLEEP_NONE);
clock_t start = clock();
for (int i=0; i<1000; i++)
{
Sleep(5);
//mark = Timer();
//SyncWait (mark, interval);
}
clock_t end = clock();
char str[128];
sprintf(str, "time elapsed %.10f millisecond", 1000.0*(double)(end-start)/(double)CLOCKS_PER_SEC);
MessagePopup("time elapsed", str);
SetSleepPolicy(VAL_SLEEP_MORE);
The actual time elapsed it about 5900 millisecond, it is 800ms more than the labview case. I try to change the SleepPolicy to SLEEP MORE, SLEEP SOME and NONE SLEEP mode, about the same. I wonder if using clock() method to estimate time is not a good way or not.
I also post my project file here. The labview code as well as the CVI are running in 2013 version. Thanks.
11-05-2013 09:07 AM
@Wolfgang wrote:
No, it can be used with regular run-time engine.
You can have a look at the sample samples\toolbox\asyncdem
It sounds great. I found an example here (http://zone.ni.com/devzone/cda/epd/p/id/2720) and though I don't know much about it, by running the code, it seems that the timing works pretty great. I still don't know how to apply that to delay the code and I will read the toolbox example, thanks.