C# HMI @ 64 FPS

I did a lot of work in C#/Forms a few years back and found it to be a bit to slow for actual usage. It was easy to get fancy UI graphics done, but you instantly started struggling with performance on the screen. I remember using ca 1 month to get the functionality done and several months to get the UI library to perform. Basically I gave up using C# on SCADA style Applications at the time for reasons I will demonstrate below. Friends of mine recently claimed that the x64 flag in C# was native compilation, so I just had to try it. I don’t know about native compiling, but the result is much, much better.

This little test consist of a small plot and a fast, real-time grid running (above) on 1920×1080 screens in full size. It is a brute force implementation where I redraw the entire screen as fast as I can and the result stare me in the face – 64 FPS (Frames Per Second) at 6% CPU load. I have tested on 3 full screens as well and the CPU load increase a bit, but I still have 64 FPS. Ok- this is not the most Advanced Graphics, but it is a very convincing proof of concept, so I decided to re-create a heavier test that failed before.

Testing with AnyCPU flag I notice that I achieve the same with 22% CPU load. I also tested with .NET 4.7.1 and performance dropped, so I am using .NET Framework 4.6.2. The .NET version I basically gave up was .NET 4.0, which is the first version that started introducing the changes that now have matured. I also do a programming trick involving updating the screen from timers.

The computer I have in front of me is an Intel Core i7-4710HQ CPU @ 2.50 Ghz. It is a 64 bit with 8 cores, an old Asus gaming computer that is ca 5 years old. The second computer I tested is a bit faster, but results was basically the same. And just to be clear – this is the CPU doing the work on classic Form programming, not the GPU. What I will do next is to invest in heavier HMI Graphics and test.

The next picture below show the heavier test. Here I have 3 plots and have populated them with random lines. This is sadly also where C#/.NET starts to fail.

The logic I use here is that I run 2 timers – one to feed data and one to send Invalidate() to the component. The three plots are updated in sync so they should have reached the same level on the x-axis, but as you can see they have not.

What happens is that as the plot get heavier the framework simply stop updating some of it’s components. In this case you can see that the top plot has fallen far behind, so have the next plot and it is only the bottom plot that get updated at this point. The CPU load is 20%ich.

So – a short question – how can you trust a framework with critical HMI if you can trust the screen being updated properly? The answer is simple – you can’t!

I admit that faster CPU’s, newer and better .NET Libraries and the x64 setting all make good performance improvements. But, at the end it only moves the threshold for this Critical error.

And yes – I know how to get around this – I can daisy-chain all components and force them to update.

Leave a Reply