So, I'm building a WPF app and did a test deployment today, and found that it performed pretty poorly. I was surprised, as we are really not doing much in the way of visual effects or animations.
I deployed on two machines: the fastest and the slowest that will need to run the application (the slowest PC has an Intel Celeron 1.80GHz with 2GB RAM). The application ran pretty well on the faster machine, but was choppy on the slower machine. And when I say "choppy", I mean the cursor jumped even just passing it over any open window of the app that had focus.
I opened the Task Manager Performance window, and could see that the CPU usage jumped whenever the app had focus and the cursor was moving over it. If I gave focus to another (e.g. Excel), the CPU usage went back down after a second. This happened on both machines, but the choppiness was only noticeable on the slower machine. I had very limited time to tinker on the deployment machines, so didn't do a lot of detailed testing.
The app runs fine on my development machine, but I also see the CPU spiking up to 10% there, just running the cursor over the window.
I downloaded the WPF performance tool from MS and have been tinkering with it (on my dev machine). The docs say this about the "Frame Rate" metric in the Perforator tool:
For applications without animation,
this value should be near 0.
The app is not doing any heavy animation, but the frame rate stays near 50 when the cursor is over any window. The screens I tested on have column headers in a grid that "highlight" and buttons that change color and appearance when scrolled over. Even moving the mouse on blank areas of the windows cause the same Frame rate and CPU usage (doesn't seem to be related to these minor animations).
(Also, I am unable to figure out how to get anything but the two default tools--Perforator and Visual Profiler--installed into the WPF performance tool. That is probably a separate question).
I also have Redgate's profiling tool, but I'm not sure if that can shed any light on rendering performance.
So, I realize this is not an easy thing to troubleshoot without specifics or sample code (which I can't post). My questions are:
What are some general things to look
for (or avoid) in the code to improve
performance?
What steps can I take using the WPF
performance tool to narrow down the
problem?
Is the PC spec listed above (Intel Celeron 1.80GHz with 2GB RAM) too slow to be running even vanilla WPF applications?
Are you applying any BitmapEffect-s to your UI elements?
They are not handled by GPU, so CPU takes care of rendering them. If not used properly (e.g. having a OuterGlowBitmapEffect applied to a large complex element) they can have terrible impact on performance.
Also, you still might want to try profiling your app with a performance profiler. Just to see if it's not your code that causes this.
This is not normal for WPF - I'd suspect one of your developers has written code that runs a timer in the background (or more likely given your description, a mouse move handler) which is affecting the UI in some way.
If you have ANTS performance profiler (it's really nice) I'd run that over your app and reproduce the problem.
Once you've done that, ANTS should tell you fairly quickly what the problem is.
If ANTS doesn't reveal anything at all, and shows you that in fact none of your code is running during this time, then I'd suspect buggy graphics card drivers.
You can test for this by disabling hardware acceleration by setting the following registry key, and trying again:
HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics\DisableHWAcceleration to 1
Note: the DisableHWAcceleration value should be a DWORD
Related
I have come across a strange situation and do not know what or how to look for.
We are having a Silverlight project hosted in a web project. This Silverlight project communicates using REST services hosted by the web project.
Now when we run this in debug mode, Everything runs fine as expected. So I thought of profiling it and checking which all places I might be loosing performance. So here is the interesting part.
I ran VS2012 Profiler and its is collecting all information related to methods executed, time and so on. But this time my project is lightning fast. Queries which used to take under normal debug about 1 sec to execute are now taking less than 200ms. There is one very intensive query which takes about 20 sec to execute in normal mode, but under profiling it takes less than 600ms.
So what I make out of this is that my code and project is capable of running this fast but for some reason it is not that fast under normal debug scenarios.
Can somebody throw light as what is happening under the hood and how can I achieve this performance in normal scenarios.
I would also like to mention that I have also tried release mode and publishing to IIS but none of these give as good performance as when in profiling mode.
Technically what I thought earlier is under profiling mode, performance should be less than normal as at that instant VS2012 is also collection other data.
I am confused. Please help.
Thanks
I know you probably don't need help at this point, but for anyone else who stumbles upon this post, I'll give my two cents.
I had this same problem with an XNA project I'm working on. Debug and Release modes both saw MASSIVE slowdowns in a certain situations. It pulled me down to less than 1 FPS. I was trying to profile the problem to solve it, but the issue never occurred during profiling.
I finally discovered the slowdowns were caused by a Console.WriteLine() I was calling in the situation. Commenting it out solved the issues on both Debug and Release build. Apparently, Console.WriteLine is just INCREDIBLY slow.
I'm about to deploy my new WPF application and I've just noticed in the Task Manager that it was consuming a lot of memory. So I downloaded a trial of RedGate Antz to try and find out what was causing this issue and I was shocked to see about 90 MB of unmanaged memory usage. Because Antz does not support unmamaged memory I then tried to use Windbg which did not point to a high usage itself. This leads me to believe it must be one of the DLLs I'm loading. I'm using the DevExpress controls in my application.
An interesting feature is when I minimize my application the memory drops right down from say 110 MB to about 6-10 MB.
Should I be concerned / worried?
This is my first WPF application and I'm not totally sure what to expect in terms of memory usage. Does the fact when minimized this memory is regained/given up a sign that everything is ok?
Any thoughts or ideas on what could be causing this would be most helpful.
I've had good luck with SciTech's .Net Memory Profiler (memprofiler.com) if you want to know specifically what's causing it.
With the nature of the .Net runtime, if you're running on a machine that has plenty of memory available then it will generally try to use it. If you start seeing performance problems related to it then you should worry, and generally it's good to be aware of what is using resources regardless. A probable reason for the drop in memory is one of the DLLs may hook to your main Window's events and invoke a garbage collection on minimize.
If you're concerned about the perception of high memory usage there are tricks you can play to massage the numbers that show up in TaskManager (like p/invoking SetProcessWorkingSetSize), but that doesn't seem to be really what you're asking about.
I have a WPF Canvas with about 240 paths. A path may go out to column 550 when I look at it in Visual Studio. It's a picture of a handheld remote with many buttons that was originally exported from adobe illustrator.
On a dual core machine, 4gb, when I show the graphic, it can spike the processor from a normal of about 10% up to 30% to 40% and it will stay there. There's nothing going on, just sitting there. Probably nothing special with respect to the graphic card. If I hide the graphic, the CPU usage will drop back down.
On a better machine with more cores (I7) and a better graphics card, the change is not really noticeable, but still a spike none the less.
Anyone share a similar experience?
WPF need powerful processor to work smoothly. But in case of lower h/w it gives lower performance, specially when animation is used.
Reduce the frame rate of animation
Do not use transparency unless it is required
Use dispatcher to smooth the UI
We were able to solve a high CPU usage problem by taking advantage of Silverlight's bitmap cache, as described here:
Silverlight 3 and GPU Acceleration
Discovering Silverlight 3 – Deep Dive into GPU Acceleration
We added the EnableGPUAcceleration parameter to the <object> tag. To bring the CPU usage down to a reasonable level, we had to add CacheMode="BitmapCache" to the root visual grid for the whole app. So I'm wondering if there's any downside to relying so much on the bitmap cache. If it was always beneficial, I assume it would be enabled by default.
I found this similar question with a good answer by AnthonyWJones:
Any reason not to check “application library caching” and “GPU acceleration” in silverlight apps?
So one downside is that it uses more video RAM. I guess this could make things worse for other graphics-intensive apps running at the same time. Are there any other downsides?
If the graphics card doesn't have enough video RAM to cache everything, I assume Silverlight will degrade gracefully and will just use more CPU cycles to re-render the UI.
Thanks for your help,
Richard
After experimenting a great deal with bitmap caching, we ended up turning it off in our application. It works well when you're wanting to use the GPU to execute transforms on a piece of your UI that isn't changing -- for instance, if you have a picture that you want to animate, squish, rotate, etc. But bitmap caching/GPU acceleration (in its current implementation) slows things down pretty dramatically if you're continuing to update the visual tree inside the part of your UI that you'd like to cache/manipulate. If you're just moving around a static bitmap, it makes sense to cache it and use the GPU to accelerate it. But quite often, you might be tweaking pieces somewhere down the visual tree from the piece of your UI that you flagged to cache, and if that's happening, you need to update the GPU's cache each frame, and that's slow, slow, slow.
In other words, whether it makes sense for you to turn it on or not depends entirely on where you turn it on, and what your application is doing. Because of this, my strong recommendation, if you're using bitmap caching, or if you're experiencing performance problems with your Silverlight UI, is to (temporarily) enable cache visualization and redraw regions. Makes your app look funky as hell when they're on, but they're invaluable when it comes to seeing what your UI is doing that's chewing up all your CPU.
I don't see concerns in what you described, but I believe you can over use bitmap caching.
Say for instance you had a 500x500 'top' canvas, and it contained 25 'sub' canvases each 100x100. Lets say we were updating content/colors, etc.. in each of the sub canvases. Lets say there was an event that would move the top canvas on the screen. If all the sub canvases changed at the same interval, it would make sense to only bitmap cache the top canvas. However, if the sub canvases did not all change at the same interval, or sometimes not at all, it could turn out to be more benefitial to set bitmap caching on each sub canvas instead. Taking this one step further If you bitmap cached both the top and each sub canvas, there could be wasted cycles in caching something with no benefit.
Or am I going down a completely different path than what you are asking?
I have a simple fade in animation on a large Rectangle inside a ScrollViewer and I notice a significant drop in performance when I increase my windows size past a certain size.
resolution: 1650x1256 - still feels snappy and fluent (framerate between 50 and 60)
resolution: 1820x1256 - stutters and is pretty much unusable (framerate between 7 and 15)
What surprises me is that there doesn't seem to be a linear decline in performance but a rather sudden drop.
Also using Wpf Performance Tool does NOT show any software rendering and indeed my CPU doesn't seem to be doing much when the animation runs.
I would like to understand the cause of this, any hints would be appreciated.
Another possibility is that you are running out of dedicated video memory at that resolution, so DirectX is transferring a lot of data back and forth between video memory and main system memory on every frame.
Is there any way you can try a different graphics card, or one with more RAM, to see if the problem changes?
Also, does your GPU have a way to configure how much system RAM is reserved as video memory? Some do.
My guess is that you are running out of GPU memory at that point, so DirectX is dropping back to software rendering.
When you say a "viewport", do you mean a ViewPort3D, or do you mean a Viewbox? If it is a Viewport3D, is the animation really needing the 3D processing? If not, you could use 2D and use a transform to simulate 3D the way Flash applications have to do.