question

Upvotes
Accepted
322 5 12 16

UPA High CPU Usage?

Please can you help?

I am using the UPA API on ASG and I am finding that the thread handling reading and writing to/from UPA API is having 100% CPU. I have done a g profile analysis and the results are attached. They show that some functions have a lot of the CPU time:

ripc10IntFlushSess – has 28% of CPU cycles

writev – has 55% of CPU cycles.

One run had number of in/out UPA buffers set to 300,000 and the other had them set to 50000 and the results were the same.

elektronelektron-sdkrrteta-apielektron-transport-apimulti-threading
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

1 Answer

Upvotes
Accepted
791 9 7 14

The threading framework and how UPA’s interfaces are driven is controlled by the application that uses UPA, not by or as part of UPA. This is especially true for the TCP transport which you are using, where UPA does not have its own thread and it does not create any threads as well. The results you see indicate that the application is calling UPA with this level of frequency.

I would suggest looking into the code that ASG has written to drive UPA. The flush functions you show are the UPA methods that push content out to TCP, writev is the actual socket write method call used by UPA. These methods do a lot of the heavy lifting for output of data, but suspect they are using this much CPU in both of your cases because the threading framework is calling it when it does not need to (e.g. when TCP cannot take any more bytes)

Since this is driven by the application, there are several ways that rsslFlush can be called – each of these provide slightly different outcomes and depend on the applications needs.

1) Use I/O notifier to tell the app when TCP can take more bytes. This is accomplished by using the socket ID given by UPA in the applications I/O notifier for write notification. This notification will fire when TCP can take bytes, so typically it is only registered when the app has bytes it needs to push out. For example, if rsslWrite returns positive, the app can call rsslFlush. If rsslFlush returns positive, it will register for write notification – when write notifier triggers app it calls rsslFlush again. When rsslFlush returns 0, write notification is unregistered. Unless TCP can always take more bytes and your app always has something to write to it, this should result in less CPU use, but there will be a slight latency increase due to I/O notification overhead.

2) Tight loop on rsslFlush. Suspect this is what your framework is doing now based on what you see. This will guarantee the lowest latency, but eats up most CPU because the app is telling UPA to constantly try to push data to TCP, even when TCP cant take anymore. This results in the calls you would see repeating and repeating.

3) Call rsslFlush based on some application controlled timer so it can call every x milliseconds. This will add latency (because of the time based approach) but will end up using less CPU than approach #2. You will have to choose the one that works best based on what your application needs are. Option 1 tends to work well if you do not already have timers for other things, so you may want to consider this approach in the testing you will do.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Click below to post an Idea Post Idea