I've got an application where I am processing images from a camera at around 20Hz. Each image is segmented into a matrix of regions, let's say 100 x 50 (for example). Each region is processed, resulting in a single floating point metric. I'm trying to create simple 2d plot for each region's data as it is created. So, on the screen would be a matrix layout of 500 (in this worse case example) plots/charts.
I'm currently processing the images without issue using managedCUDA and writing some CUDA kernels to take care of that. What I'm faced with now is trying to create a way to logically view all this data has it's coming in. Things I've considered:
Building an "image" on the gpu with dimensions matching the target display control. This image would be segmented into the appropriate number of regions and a rudimentary chart would be drawn, pixel by pixel.
Learn Direct3D or OpenGL and code the algorithms necessary to draw the charts
Use the native WPF capabilities to draw the charts myself.
Use a commercial or open-source charting tool
Option 1 seems crazy to me (but I had a gpu-centric friend suggest it).
Option 2 seems like I'd have to learn all the unnessary 3D overhead of D3D or OpenGL just to draw 2D plots.
Option 3 and 4 probably have the most appeal to me, but I'm worried about performance.
So just looking for advice before I charge off in one of these directions.
I thoroughly recommend SciChart if you have the money. We develop scientific software that need to process large amounts of data being received from external devices, and have found SciChart to be excellent (features and performance). And no I'm not affiliated to them in any way!
Like all charting components it takes a while to get your head around the many features, but it's worth it. If you download their trial it includes a load of samples, including demos of real-time performance.
Related
I'm currently looking at writing a sound wave visualisation control for WPF. In fact it can render any sort of line graph data; it doesn't have to be a sound wave. As long as the data is a discrete set of samples it will render it.
I have it working; however the performance is not that desirable. I have done a lot of code optimisation to make the OnRender method work quickly. I've tested it with a profiler and it shows it runs at around 110ms, which should be fine.
However I'm seeing the application stall a lot and the profiler isn't showing why.
During my tests I've noticed it may have something to do with fill rate. By that I mean the number of pixels being drawn. My test data consists of a sin wave, at 41000hz over 20 seconds. This produces 812000 samples. Now my control optimises this data depending on the zoom scale the user is viewing the wave at. The entire wave will be drawn using around 6000 lines draws.
If I zoom a long way into the wave so I only render two full sin waves, I still do around 6000 line draws. The CPU time is around the same, at 110ms but the application is smooth and doesn't stall, which seemed strange at first.
However when looking at it the full wave draw touches almost every pixel. The chart draws a green line, which when zoomed out overwrite the entire background of the graph control. When zoomed all the way in only a small amount the background is overdrawn.
I work as a game programmer so I recognise this issue could be caused by fill rate limits. If the line draw is touching every pixel then it becomes slow to draw, irrespective of the number of line draws. However I would not expect this to be the case as the graph isn’t that large on screen. If I change the size of the window then it does get slower, which again reinforces by guess at fill rate issues. A modern graphics card should be able to handle this so maybe the control is using software rendering. I'm not sure how I can prove that!!
So my OnRender method is pretty optimised as far as the logic goes. In both of the above cases the time it takes to draw, on the CPU, doesn't change much. However in some cases there is a terrible lag of around one second if a lot of pixels are touched.
Does anyone know how I could improve this?
One way I have considered is to render an off screen texture on another thread and once complete, then call InvalidateVisual once the texture has been updated. I could also do the invalidation every so often so the graph rendering updates over time, rather than just suddenly appears.
Anyone have experience of this sort of thing and how do I actually profile the internals of WPF?
Does anyone know a profiler that will show me what is actually causing this, but as I said I think it maybe down to the actually hardware render and a fill rate problem.
Just to note, my graph control inherits from Canvas and the line draw is done using StreamGeometryContext. I also freeze the geometry and all the brushes and pens.
Thanks
I write software that needs to graph large amounts of frequency sprectrum data very fast. WPF's retained graphics system isn't very good for drawing (graphing) large amounts of data that is changing frequently. We use D3D9 to draw our graphs. WPF provides a way to get this into their rendering system through the D3DImage class where it can become an ImageBrush. Thus, it avoids problems relating to airspace restrictions at the cost of a little performance, but will still be much faster than rendering with WPF objects.
There are also two very good graphing libraries that I have seen out there that have different pros/cons.
SciChart is actually a software based rendering charting tool for WPF but has good performance.
Lightning Chart Uses DirectX (Via SlimDX library which is a managed .NET wrapper) and is extremely performance oriented.
Regarding your question about software rendering... The WPF Performance Suite has profiling tools and overlays that can show which portions of your application are being software rendered. You may want to download it from Microsoft and give it a try.
From what I've read, WPF's rendering system is hardly optimal (A Critical Deep Dive into the WPF Rendering System). For what WPF is designed for, it is great, but it has its limits as well.
My recommendation is that if you have experience in game development and DirectX, and you need a method to graph larger amounts of data quickly, to look through interop with D3D via the D3DImage class in WPF.
I'm designing a game and thinking about using WPF for making a simple prototype of the basic gameplay.
Is it possible to render basic 2d-graphics in WPF in real-time? By basic graphics I mean simple shapes such as lines, circles, etc. By "real-time" I mean things are rendered based on parameters such as velocity, acceleration, etc. that changes depending on player input - which I assume means I can't use storyboards for the animations.
Thanks
Check out the previous question High Performance Graphics using the WPF Visual Layer for a good related discussion. While WPF provides a great framework for rich vector graphics, it lacks somewhat for real-time 2D performance.
There are workarounds, for instance, depending on your scene complexity you may get away with using DrawingVisuals or virtualized Shape classes (WPF Vector graphics) to draw your sprites. Going a little lower level, you could cache sprites using the BitmapCache mode available in .NET4.0, or pre-prendering them to Bitmaps and using various optimization patterns to improve throughput.
Going lower level still, you can mix Vector/Raster graphics using the fantantastic WriteableBitmapEx project, or Vector/GPU graphics using the D3DImage.
Regarding how to update your scene, you'll need to write a primitive game engine where on the CompositionTarget.Rendering event (fired on redraw of the screen) you get the updated parameters and compute positions/orientations of your sprites. Something that might help with this is this great codeplex project which integrates WPF/Silverlight and Farseer physics.
I am designing an WPF application which renders data as a 500x500 8-bit indexed image at 10 frames per second using WriteableBitmap.
We would like to add some real-time image processing algorithms to our output, such as 2-D median filtering, gaussian blur or moving average, which are computationaly power hungry.
Did anyone try to use WPF pixel shaders to do such tasks ?
Would a platform-specific image processing library be efficient ? (e.g. Intel IPP ?)
Or would a DirectX based custom renderer be the solution ?
Any tip would be much welcome. At the moment everything is computed within our .NET application and I believe there is room for optimization.
Thank you for your help,
Best Regards,
Romain
If your data is purely for display I would recommend using pixel shaders. The other two options you suggest both require interop with unmanaged code which adds complexity.
I've been looking into Silverlight charting controls to display a large number of samples, (~10,000 data points in five separate series - ~50k points all up).
I have found the existing options produced by Dundas, Visifire, Microsoft etc to be extremely poor performers when displaying more than a few hundred data points.
I believe the performance issues with existing chart controls is caused by the heavy use of vector graphics.
Ergo one solution would be a client-side chart control that uses the WritableBitmap class to generate a raster chart.
Before I fall too far down the wheel re-invention rabbit hole - has anyone found a third party or OSS control that will manage large numbers of data points on a sparkline?
Check out Visiblox ( http://www.visiblox.com/ ) Charts. I'm working on a telemetry application at the minute which uses three of their charts in the same Silverlight component, plotting about 36,000 points in total, and there is very little slowdown in terms of performance, if any at all.
They have a high performance example on their website here - http://www.visiblox.com/examples/LargeDataSets. I chose to use Visiblox after loooking at the following blog post:
New performance comparison: http://www.visifire.com/blog/2011/12/02/fast-silverlight-charts/
Old performance comparison: http://www.scottlogic.co.uk/blog/colin/2010/12/visiblox-visifire-dynamicdatadisplay-charting-performance-comparison/
My telemetry example is now part of a CodeProject article that I have created, if you want to take a look!
Based on the recommendations here, I have just trialled Visiblox and Infragistics.
Visiblox has a good developer experience, clean APIs, no bloat. While the performance is OK for a few thousand datapoints, performance breaks down as you go into the 100k range. Here's the Visiblox sample with a few thousand points (you can download the sample and just tweak the number of datapoints).
Now, the common argument here is that you should not bind that much data to a chart anyway, but should do some trimming beforehand. I do agree with that, but ideally, I want a chart control that does take care of that for me. Getting Zooming, Panning and all that right are non-trivial tasks and I'd be happy to shell out a few 100$ to get that functionality. It's plain economic common sense to not reinvent the wheel here.
Infragistics certainly gets that right. I can bind a million odatapoints and get smooth peformance. Here's the Infragistics sample.
However, Infragistics installs a lot of junk (a local IIS web app with the samples you can also see online) and besides the (excellent) samples and the code-level documentation, I do miss some high-level introduction to each component and it's individual modules.
Since a lot of people on SO recommend Telerik controls for their clean APIs, Documentation and Developer Support, I did also take a look at their chart control. However, I must admit I find it rather slow (Zooming takes roughly 500-1000ms, which is too long to feel smooth).
Here's the Telerik sample.
Visifire is the fastest chart now. Check out the blog link below.
http://www.visifire.com/blog/2011/12/02/fast-silverlight-charts/
The Chart image says Visifire is 3 to 4x faster than Visiblox..!
Before you start playing around with WritableBitmap on your own take a look at WriteableBitmapEx from René Schulte, he blogs about it here. Awesome stuff.
I don't know of any OSS or 3rd party controls that'll do what you need.
The one case where I've had the need for 100K+ of datapoints, we made it work by keeping it simple. The biggest perf killer was the number of elements within each datapoint. By keeping the element a simple ellipse with a static brush fill the app was rather snappy.
Infragistics claims to be able to handle massive amounts of data in their recently released xamDataChart.
http://www.infragistics.com/dotnet/netadvantage/silverlight/data-visualization/xam-web-data-chart.aspx#Overview
I believe the Telerik sample you are looking for can be found here. It shows large amounts of data that you can actually zoom in/out of. They also have a Server Load "Performance" Demo as well. Here is an example of the Scatter Chart with hundreds of data points.
Have you looked at the Telerik charting controls? Here is a link to one of their demos where they are using 100.000 data points:
http://demos.telerik.com/silverlight/#Chart/Sampling
I should also mention that I have not used the charting controls myself, so I cannot vouch for them. But the demos look good to me.
EDIT:
The link above has gone stale. Here is a link to the latest incarnation of the Telerik charting control They call it ChartView now:
http://demos.telerik.com/silverlight/#ChartView/FirstLook
Approaching Silverlight development is a rather daunting task as it seems to require a rather different mindset to work I have done in the past.
I have been working on it for several months and we have already released an application that presents form-based pages. So I have the basics of XAML for layout but what I need to do now is move into graphically representing data. For example transform a list of objects representing vehicle speed recordings into a line graph of speed. I am at a loss on what the best way is to approach this.
Can anyone point me to articles or tutorials that present this kind of thing?
Your first port of call for Silverlight learning should be the official site http://silverlight.net/Learn/
If you want to do any data visualization/charting then first try the Silverlight Toolkit on codeplex. It's fantastic if you want to get anything up and running quickly.
Also check out Delay's Blog on charting and the chartbuilder code
Bang your head against it for 3-6 months. That's how I did it and it's worked out pretty well so far.
But seriously, the learning curve sucks.
There's charting libraries for Silverlight out there, you could grab one of those but I wouldn't waste money on it. It's relatively easy to write this kind of code yourself.
All you really need is a DrawingVisual. Once you have that you can render what you need on to it's surface. The trick is to make sure that you have sufficient layout information when you render. Because this is vector graphics, you can use the ScaleTransform to match your content bounds instead of repainting on size changed. Other than that, you'll wanna host your DrawingVisual in a UIFrameworkElement and let the dimension of that object govern where and how you draw your data. This will give you all the layout goodness of WPF/Silverlight.
For drawing there are plenty of Geometry classes you can rely on but there's one thing that you'll wanna do and that's to adjust the level of detail in your data points with respect to your drawing. This is the number one trick to make sure you don't hog the CPU.
Avoid drawing more than one data point per pixel. If you have a lot of data points, and a small drawing surface you can use a rolling average to smooth the result.
If you approach this with the above things in mind you should be able to write a flexible graph UI element that you can visualize data with, in no time at all.
I did this in a WPF application, I'm pretty much assuming that you can do the exact same thing with Silverlight 2.0, you'll just yell at me if you cant?