-
How to reduce high CPU usage caused by receiver thread of CAN messages?
Hello,
I am struck with a serious issue and not able to get through it.I am writing a program which handles the CAN messages Received from BUS.My code is taking almost 60% of CPU usage.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Adding ::Sleep() to code doesn't "solve" anything.
At best it can give you a false perception that something is running "better" under the specific circumstances you're testing it on. On another computer, with another resource load, other cpu, memory... You may very well have made things even worse by adding that Sleep().
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
So is there any other way to solve this issue.i am thinking that the buffer size for the receiving CAN messages is not large enough.So by creating larger buffer will solve this issue?
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
What "issue"?
CPU usage isn't necessarily an issue, as long as real work is getting done. If you are in a hard-spin waiting for data, then a blocking API would be better (as discussed in the other thread).
What CAN library are you using - and how are you using it?
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
Codeplug
What "issue"?
CPU usage isn't necessarily an issue, as long as real work is getting done. If you are in a hard-spin waiting for data, then a blocking API would be better (as discussed in the other thread).
What CAN library are you using - and how are you using it?
gg
But for my case its an issue,because of High CPU usage the performance of HMI is degrading.After 3 hours of continuous HMI Pc getting slower.
I am using XL Driver library.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
>> My code is taking almost 60% of CPU usage due to the Receiver thread used for receiving CAN messages.
Not sure how to help without seeing some real code - other than "don't call Sleep" and follow the advice in the other thread.
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Just google'ing the documentation for xlReceive(), I can see that it isn't being used correctly (msgsrx is uninitialized). It also appears that xlReceive() is always non-blocking, so you're code will be in a hard spin doing a whole lot of nothing while XL_ERR_QUEUE_IS_EMPTY is returned.
Look into the xlSetNotification() API. This will give you a Win32 waitable handle that can be used to wait efficiently for messages to come in. Also consider calling xlReceive() to read more than just 1 event at a time.
Read this for how to post code on this forum: http://forums.codeguru.com/misc.php?do=bbcode#code
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
Codeplug
Just google'ing the documentation for xlReceive(), I can see that it isn't being used correctly (msgsrx is uninitialized). It also appears that xlReceive() is always non-blocking, so you're code will be in a hard spin doing a whole lot of nothing while XL_ERR_QUEUE_IS_EMPTY is returned.
Look into the xlSetNotification() API. This will give you a Win32 waitable handle that can be used to wait efficiently for messages to come in. Also consider calling xlReceive() to read more than just 1 event at a time.
Read this for how to post code on this forum:
http://forums.codeguru.com/misc.php?do=bbcode#code
gg
Can you please tell me how to avoid the non-blocking of xlreceive().I tried adding xlSetNotification() API in my code.And how can I call xlreceive() to read more than 1 event at a time?
Please help me with this.I am nearing the deadline.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Have you also included the WaitForSingleObject(..). This is the how you write non-blocking code. It's described in the manual together with examples of how its used. RTM!
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Code:
_declspec(dllexport)
int receive_data(unsigned char *data_output, int *MsgId, XLportHandle g_xlPortHandle)
{
XLstatus xlStatus;
XLevent xlEvent;
unsigned int msgsrx = 1;
Xlhandle h = 0;
if (!g_RXThreadRun)
{
// TODO - log that we are shutting down?
return XL_ERROR;
}
xlStatus = xlSetNotification(g_xlPortHandle, &h, 1);
if (xlStatus)
{
h = 0;
// TODO - log error, and that xlReceive() will be non-blocking
}
if (h)
{
// TODO - allow caller to pass in the timeout
const DWORD timeout = 3000; // arbitrary
DWORD status = WaitForSingleObject(h, timeout);
if (status == WAIT_TIMEOUT)
{
return XL_ERR_CMD_TIMEOUT;
}
}
xlStatus = xlReceive(g_xlPortHandle, &msgsrx, &xlEvent);
if (!xlStatus)
{
// TODO - allow the caller to pass in their own XLevent object (and count)
memcpy(data_output, xlEvent.tagData.msg.data, 8);
*MsgId = xlEvent.tagData.msg.id;
}
return xlStatus;
}
See if that helps your CPU usage any.
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
You will have to profile your code to see if the CPU usage is due to real work being done, or if the code is still "spinning" needlessly in places.
>> After 3 hours of continuous HMI Pc getting slower.
Use something like ProcessExplorer to see if your app has a resource leak (memory or handles) that may explain the degradation over time.
http://channel9.msdn.com/Shows/Defra...ocess-Explorer
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
Codeplug
You will have to profile your code to see if the CPU usage is due to real work being done, or if the code is still "spinning" needlessly in places.
>>
After 3 hours of continuous HMI Pc getting slower.
Use something like
ProcessExplorer to see if your app has a resource leak (memory or handles) that may explain the degradation over time.
http://channel9.msdn.com/Shows/Defra...ocess-Explorer
gg
I have used this tool and I have seen that there is no memory leak.The CPU usage is mainly because of receiver thread which is continuously running,that is used for receiving messages from CAN Bus.The messages come at a rate of 40 milliseconds but this thread is running at a rate in microseconds so increasing CPU usage.So i wanted to know if anything else can be done in the code,which I attached earlier to reduce this fast loop?
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
If the new code is calling WaitForSingleObject(), then xlReceive() should efficiently return a message on every call - which is followed by the real CPU work of processing that message.
So assuming the CPU usage reflects real work, why do you want to reduce it?
Are you looking to "sample" less than 25 messages a second?
Or do you want to process all 25 messages per second, but use less CPU than you are using now to do so?
If it's the later, then you will have to profile your code to see where the "hot spots" are and optimize.
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
Codeplug
If the new code is calling WaitForSingleObject(), then xlReceive() should efficiently return a message on every call - which is followed by the real CPU work of processing that message.
So assuming the CPU usage reflects real work, why do you want to reduce it?
Are you looking to "sample" less than 25 messages a second?
Or do you want to process all 25 messages per second, but use less CPU than you are using now to do so?
If it's the later, then you will have to profile your code to see where the "hot spots" are and optimize.
gg
I think new messages are coming before the previously received messages are parsed.As a result the buffer is overwritten.So can you tell me am I thinking in the correct way?If so by creating a buffer of larger size can solve this issue.The incoming messages are of 8 bytes and a total of 11 messages I am getting,so I need to store all 11 messages in the buffer and then parse the data accordingly.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
What is the messages per second (msgs/s) that the current code can achieve?
If your parsing/processing code can't handle more than 25 messages a second, then no amount of buffering is going to help.
Code:
case Can_Msgs.mMAP_SPEED_INFO.msg_id:
RawCanData = xDataConv.data_to_ui64(CanData);
i = filt_CParsDbcFile.Search4Message(uMsgId);
if ( i != -1 )
{
Can_Msgs.mMAP_SPEED_INFO.last_receive_time = GetTickCount();
j = filt_CParsDbcFile.Search4Signal(uMsgId,"MapCrntPstSpdLimVld" );
if( j != -2 )
{
Startbit = (63-((int)filt_CParsDbcFile.m_pSigDescs[j].startByte*8))-(7-(int)filt_CParsDbcFile.m_pSigDescs[j].startBit);
Can_Msgs.mMAP_SPEED_INFO.MapCrntPstSpdLimVld = xDataConv.get_bool(RawCanData, Startbit);
}
}
break;
That code needs to be profiled to see what's taking so long. If that code can't handle 25 msgs/s, then which part is taking so long?
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
>> I tried commenting whole parse messages but still the result was the same
Code:
while (vThread_exit.Rcv_Msg)
{
RcvVal = receive_data(CanData, MsgId,g_xlPortHandle_global);
}
So you're saying that that code there has the same CPU usage? If that's the case, then Vector's XL Driver library requires that much CPU to get the job done.
But again, CPU usage itself isn't necessarily a problem - as long as real work is being done. Is there still a perceived "problem" with the amount of CPU usage? Or will it suffice to say "Vector needs this much CPU to get the job done"?
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
>> yes that code has the same CPU usage.
How did you confirm that it is the Rcv_Msg() thread that is actually using the CPU? What are the other threads in the application doing?
>> The Vectors XL driver library for the old code worked well.
Same version of library? Same hardware setup? Using CAN functions? What are the differences between new and old?
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
I'm not sure anything can be said about that XL lib so far.
what I can say is that the suggested receive_data() in #12 has several potential problem area's.
1) it uses a bool to check for 'thread running'.
not necessarily a problem, but this doesn't typically mesh well with uses of WaitFor...()
a bool will work well enough when you're not waiting/blocking. If you are, you really should look at using an event and waiting for your normal handle AND the event handle in a WaitForMultipleObject() call.
2) there is no need (or should be no need at least) to call the setnotification every call in the receive function.
This IS potentially the bottleneck if this creates sync objects (which is seems to do).
3) I don't know this lib, but I would expect there to be a call to stop the notification and release resources. This could could be leaking sync objects (or it may not, depending how it works). This could be part of the "getting slower" problem over time, you're running out of memory and potentially other system resources.
4) "arbitrary" timeouts without really understanding what's behind it... tend to be sources of problems. Either you don't have a timeout (infinity), or there is a clear reason why you would need this to have finite state.
If this is because you want to periodically check for the "thread running" state, then that's more indication/proof you want an event and not a bool for this purpose.
5) multithreading isn't easy. Make sure you have a proper "plan of attack" before you begin coding the thread including properly identifying/documenting all possible synchronisation issues and how you'll deal with them rather than fumbling along and making a mess of things.
If you don't know this xl library, make test applications to test the cummunication system it's based on first, then write the multithreading around how it works. don't make a thread, then try and somehow hack your way into making the thread do more or less what you want.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
Codeplug
>> yes that code has the same CPU usage.
How did you confirm that it is the Rcv_Msg() thread that is actually using the CPU? What are the other threads in the application doing?
>> The Vectors XL driver library for the old code worked well.
Same version of library? Same hardware setup? Using CAN functions? What are the differences between new and old?
gg
[QUOTE] How did you confirm that it is the Rcv_Msg() thread that is actually using the CPU? What are the other threads in the application doing?
I have used Procexp to see what all threads are running and how much CPU each thread is consuming.I have seen other threads are using around<1% of CPU.
Same version of library? Same hardware setup? Using CAN functions? What are the differences between new and old?
Yes they have used the same version of library and hardware setup.Few CAN functions differed.They have implemented the CANDll with in the code.But I have implemented the CANDll separately.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
OReubens
I'm not sure anything can be said about that XL lib so far.
what I can say is that the suggested receive_data() in #12 has several potential problem area's.
1) it uses a bool to check for 'thread running'.
not necessarily a problem, but this doesn't typically mesh well with uses of WaitFor...()
a bool will work well enough when you're not waiting/blocking. If you are, you really should look at using an event and waiting for your normal handle AND the event handle in a WaitForMultipleObject() call.
2) there is no need (or should be no need at least) to call the setnotification every call in the receive function.
This IS potentially the bottleneck if this creates sync objects (which is seems to do).
3) I don't know this lib, but I would expect there to be a call to stop the notification and release resources. This could could be leaking sync objects (or it may not, depending how it works). This could be part of the "getting slower" problem over time, you're running out of memory and potentially other system resources.
4) "arbitrary" timeouts without really understanding what's behind it... tend to be sources of problems. Either you don't have a timeout (infinity), or there is a clear reason why you would need this to have finite state.
If this is because you want to periodically check for the "thread running" state, then that's more indication/proof you want an event and not a bool for this purpose.
5) multithreading isn't easy. Make sure you have a proper "plan of attack" before you begin coding the thread including properly identifying/documenting all possible synchronisation issues and how you'll deal with them rather than fumbling along and making a mess of things.
If you don't know this xl library, make test applications to test the cummunication system it's based on first, then write the multithreading around how it works. don't make a thread, then try and somehow hack your way into making the thread do more or less what you want.
I have changed my code in #12 as per the code in #13.And I am sure that the threads I have implemented working fine except for this receive thread.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
It sounds like you're getting more messages than you expect - ie, way more than the 25 msgs/s that you're interested in.
Do you see any differences in how the port is opened and setup between the new and old code?
Looking at the CAN Application flowchart in the manual, there are setup functions like xlCanSetReceiveMode() and xlCanSetChannelMode() that seems to affect what will be received. Or perhaps it's a settings difference in in the "Vector Hardware Config" tool.
You could write some code that logs all the messages coming across that you are not interested in. Knowing what those are may help with figuring out how to exclude those so that xlReceive() never returns them.
>> 2) there is no need (or should be no need at least) to call the setnotification every call in the receive function.
The manual implies this as well - since the flowchart has this being called in the Setup phase only once.
gg
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
Codeplug
It sounds like you're getting more messages than you expect - ie, way more than the 25 msgs/s that you're interested in.
Do you see any differences in how the port is opened and setup between the new and old code?
Looking at the CAN Application flowchart in the manual, there are setup functions like xlCanSetReceiveMode() and xlCanSetChannelMode() that seems to affect what will be received. Or perhaps it's a settings difference in in the "Vector Hardware Config" tool.
You could write some code that logs all the messages coming across that you are not interested in. Knowing what those are may help with figuring out how to exclude those so that xlReceive() never returns them.
>> 2) there is no need (or should be no need at least) to call the setnotification every call in the receive function.
The manual implies this as well - since the flowchart has this being called in the Setup phase only once.
gg
All the messages which are around 11 of them has to be received in 40 milliseconds.That means approx 4 ms for each messages.But instead of getting all 11 messages once in 40 ms,these are received like almost 10+ times.I don't see much difference between how port is opened and setup between old and new code.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
bobby2387
[CODE]if I am adding same printf statement for xlstatus I am getting the CPU usage down to 7% from 50%.I am not getting the reason why?
So you added a benign "printf" statement, and all of a sudden the behaviour changes?
That sounds like a memory overwrite bug to me, and you just moved the memory corruption to another location in the program. Corrupting memory can cause things to go "slower" due to stepping on important variables (for example, a loop that is supposed to only go 100 iterations, and the variable that holds the number of iterations gets stepped on and now is equal to 2349473927).
I'm going to put odds on it that you were always overwriting memory, and the new code exposed the bug to you. If you have gone through all of these steps of commenting things out, not knowing where things are slow, etc. and you're using the same libraries, etc., then it is almost assured you've corrupted memory, and the new code is showing this error.
That is the only reasonable explanation why a simple "printf" which should have no bearing on the CPU usage would all of a sudden change the behaviour of the program. You changed the binary executable around, therefore the corruption moves to another area of the program. My advice is to take out the printf() and actually fix the problem.
Regards,
Paul McKenzie
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Yes Paul I have removed the printf. Thanks for the information.
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
Quote:
Originally Posted by
Codeplug
It sounds like you're getting more messages than you expect - ie, way more than the 25 msgs/s that you're interested in.
Do you see any differences in how the port is opened and setup between the new and old code?
Looking at the CAN Application flowchart in the manual, there are setup functions like xlCanSetReceiveMode() and xlCanSetChannelMode() that seems to affect what will be received. Or perhaps it's a settings difference in in the "Vector Hardware Config" tool.
You could write some code that logs all the messages coming across that you are not interested in. Knowing what those are may help with figuring out how to exclude those so that xlReceive() never returns them.
>> 2) there is no need (or should be no need at least) to call the setnotification every call in the receive function.
The manual implies this as well - since the flowchart has this being called in the Setup phase only once.
gg
Can you Please tell me how to set filter for CAN driver to receive only the message id,which are required?
-
Re: How to reduce high CPU usage caused by receiver thread of CAN messages?
I wish I could help more, but this thread and the other represent my only exposure to CAN bus programming. In other words, I'm just pulling what I can from the manuals.
You say the old code runs with near 0% CPU utilization. What is the difference in functionality between that and your new code?
gg