Occasionally, I get a chance to introduce our engineers, and showcase their work, through this blog. This time, it is the turn of Asad Zia, our resident expert on all things graphics and UI related. Asad and I have worked on a few projects before, notably this whitepaper on Debugging Graphics Synchronization issues with Sourcery Analyzer. I recently had a chance to collaborate with Asad again as he supported the launch of the latest Nucleus add-on for the Qt framework product. Here is Asad’s experience in his own words as he took on the challenge of debugging and optimizing a demo of a UI application built with this new add-on.
The Nucleus add-on for the Qt framework has been released! As any engineer can relate, it’s great to see months of work bear fruit. However, turning the initial proof of concept into a stable, polished product was not without its hiccups. Given I had no prior experience with the Qt framework, I share an experience here when Sourcery Analyzer helped me uncover a performance bottleneck (cpu hogging) especially in a part of code where I least expected it to be. Since engineers love to solve a problem, I hope this will be interesting to other engineers like me, working in the trenches.
An advantage of the Qt 5.x framework is that it is well abstracted for window system APIs. However, for the rest of the aspects of porting, like threading, file system, event handling etc it seems to assume couple of mainline kernels. Provided that Nucleus RTOS bears little similarity to any of the kernels Qt supports out of the box, which means anything that is not fully generalized requires careful integration. One of such things is in the idle loop. Idle loop is part of event handling mechanism. As the name suggests, this is the software loop where Qt waits for events.
Our technical marketing team prepared a Smart Washing Machine demo to showcase the new UI capabilities in the Nucleus Add-on for the Qt framework. The demo has great graphics and smooth animations. I decided to take that demo for a spin and see how it held up against the new port.
When I ran the demo, it looked fine with no visual issues. This is what it looked like.
Then I started to verify the newly written idle loop. A characteristic of well-designed idle loop is that it allows snappy response to events while keeping the CPU free rest of the time; think battery life. The first part was easy to verify just by visual inspection. For the second part I needed more visibility into the system. Trying to do this with only a debugger is awkward. One of the perks of being employed at Mentor Graphics is that I have access to advanced debugging solutions, such as Sourcery tools, for free To enable the use of Sourcery Analyzer; the trace analysis and debugging tool; I just recompiled the Nucleus RTOS with tracing enabled and it allowed me to collect trace data within a live debug session.
It is alarming, as you can see, that the CPU usage is at a 100% with the ‘UI Task’ running continuously.
At that point I realized that it would be very useful to have some visibility inside the Qt framework. Luckily, the Nucleus port of the Qt framework has trace markers added ‘out of the box’. Incidentally, the analysis agents that interpret this data are now part of Sourcery Analyzer. This was introduced in the Qt Developer Days 2013 conference. Here is the presentation.
The agents that come with Sourcery Analyzer target specific problems, like startup time, animations or response issues. In my case there was no visual problem. I needed to interpret the data from a CPU usage perspective. The trace showed a combination of good news and bad news. The good news was that the idle loop; which I set out to verify in the first place; did not seem to be issue here because the animation ticker is continuously active and Qt is always busy painting.
The fps graph at the bottom hints at the problem. It shows that the application is always pushing 30+ frames. While 30 fps at the expense of higher cpu use may be acceptable during screen transitions and responding to input, allowing it to occupy 100% CPU during idle screen is not. Reviewing the demo again, the only thing continuously updating is this little counter, which barely contributes to 5% of the screen. I did not expect it to be such a costly operation. Apparently Qt has to traverse large code paths every frame to render this.
Stay tuned for the next part of my blog wherein I explain the debugging flow and how I was able to improve the performance of the demo. Until then, if you would like to try out Sourcery Analyzer for yourself, click here to request a trial copy.
More about Asad
Asad Zia is a Staff Engineer within the Embedded Software Division (ESD) of Mentor Graphics where he specializes in graphics and user interface technology. His work involves providing differentiated UI solutions for all the different runtimes supported by ESD with expertise that spans drivers and middleware up to the application development.