Demos are using way too much CPU

Nov 5, 2011 at 12:32 PM

The demo program, specially those which does nothing after their initial drawing (For example ImageProcessor) are using way too much CPU.

This behaviour comes from the message loop in main.cpp. This message loop is using PeekMessage instead of GetMessage. PeekMessage is not blocking, it returns true when a message is available and returns false when no message is available. GetMessage wait until a message is available.

In ImageProcessor demo, m_pApp->Update() is called at a very high rate, consuming all available CPU for nothing since there is nothing to do. Update() should only be called either when Windows request it (WM_PAINT message) or when a user interaction (Keyboard or mouse with a bunch of correspoding messages) requires it. Other demos which require an animation should rely on a timer to periodically recompute a new image. For low frame rate, a simple Window timer is enough. For higher frame rates, probably a thread sleeping the require time between frames and posting a message in OK and for the highest possible frame rate, then the loop as it is now with PeekMessage is the ay to go.

What do you think ?


Nov 5, 2011 at 5:43 PM

What you are describing is exactly correct - but the approach to choose depends on the type of application that is being performed.  Typically in rendering related applications you try to render as many frames per second as possible, since this is typically used as a measure of how efficient/inefficient an algorithm is.  Of course, in your use case, you would only want to render a new frame more selectively since you are operating in an event driven application.

All of the applications are continually updating their frame output and generating new frames.  This is intentional, but in some cases (like you pointed out, the ImageProcessor) it could be changed.  Most likely I would keep all of the rendering samples working the same way for now, but other type of applications could be changed if necessary...

It is an interesting suggestion though.  Hieroglyph is definitely a rendering engine first, and then a tool element second, but if we can find a way to support both methods and provide a way to select which one to use, then I could certainly follow that path.  It could be as simple as letting the application provide an UpdateType() method, and then just having two different message pumps.  Since the application would only use one way or the other, then it should be fine to just check the application type once and then go into the appropriate while loop.

What do you think?

Nov 5, 2011 at 7:36 PM

I'm a big fan of OOP. I believe and actually do it everyday that inheritance allows the devlopper to do powerfull things with any well designed framework. By well designed, I mean here designed with reuse an inheritance in mind.

Applyed to the CPU usage issue, I would solve the issue by insolating in virtuial method the basic behaviour such as the message pump. The framework provides one way of doing things, that is an implementation, and provides the necessary virtual methods that a developer can override so that it tailors the framework to his needs.

To said it in other words, a framework would quickly becomes overcomplicated if it tries to offer a solution for every posible situation. However, the framework will stay simple and yet powerful if it is carefully designed so that standard behaviour could be overriden.

As a side note, I would say that many games exhibit an impressive frame rate, but this is totally useless. 25 frames per second is enough for the human eye. Having more than 25 frames per second doesn't change anything in the way a human see a moving object. While your are playing, you may download some file, record a DVD or do other background stuff which requires CPU. Having a game producing 50 frames per second would compromise the good execution of such background tasks. I could understand that not so long ago, before the event of GPU's, a game required 100% pour CPU power. This is no more the case and a significant number of peoples like to do bakground tasks, if not several games at once (Well, actualls the same game but several instances or accounts). All in all, correctly using the CPU will help many users, even gamers.


Nov 5, 2011 at 8:10 PM

That's a good idea actually - and most other frameworks that I know of work in a similar manner.  Moving the message pump into the application would allow for customized message processing, including the ability to decide which form of updating and message wrapping would be used.  I'll start thinking about how to carry this out, and will get the implementation worked out within the coming weeks.  There are quite a few other things that I have queued up, so it might take a little while until it is ready though...

About the frame rate issue - I understand your point, although I would disagree with your numbers.  There is a visible difference between running at 25 and 60 frames per second, at least in my opinion.  However, this doesn't account for varying framerates.  Depending on what algorithms are being used, and which objects are visible, the frame rate can vary significantly from frame to frame.  Having some padding helps to ensure that the frame rate doesn't dip too low.

One other point to consider is that in modern games, the CPU can often still be the bottleneck - especially with very high end gaming systems that have very powerful GPUs.  This is what makes multithreaded rendering such an important topic - you can spread the CPU costs across multiple threads which helps to amortize the costs.

Nov 6, 2011 at 8:10 AM

The application class should have the message pump spread into a number of virtual functions:

ProcessMessage: This is basically PeekMessage without loop. Returns false if no message has to be processed. Retruns true if a message has been processed. Before processing a message, it has to trigger an application event which may mark the message as handled or not. Then if not handled, TranslateMessage and DispatchMessage are called so that processing is done. If WM_QUIT is received, then no processing is done but a member variable "Terminated" is set to true.

ProcessMessages: A simple do nothing loop calling ProcessMessage until it returns false.

The application class has a hidden window which will serve as a parent for all windows in the application. The main window is just a window like any other.

A base class should also created for each window. Name it WinControl. It has the required WindowProcedure to handle messages related to that window. In the window class, you allocate extra data so that you can save the pointer to the C++ class instance reference corresponding to the window. This permit to call methods of the object as window message handlers and benefit from class inheritance and methode override to customize what is needed for a specific application. Each message you must handle in the framework correspond to a virtual method named "DoXYZ" with XYZ a name related to the message (WM_PAINT => DoPaint).

-- Francois Piette

Nov 6, 2011 at 2:35 PM

That sounds like quite a framework - in fact, it sounds quite similar to what MFC or WxWidgets utilizes.  To be perfectly honest, I wouldn't mind adding further support for this style of application model.  However, I won't have time to implement such an extensive overhaul for quite a while.  Since you have experience in the area, as well as desire to see it implemented, would you consider contributing code to the library that provides this type of application model?

This could be done in parallel to other development, and then added in once it is ready for integration with the rest of the library.  What do you think?

- Jason

Nov 6, 2011 at 3:27 PM

Wouldn't be better to make the framework compatible with MFC or WxWidgets then ? Or even make it as possible as independent of any GUI framework ? I don't have - yet - enough knowledges about Hieroglyph3 to really understand if this is easy or not to achieve. In my opinion, building a new framework for GUI is not the best idea we could get. Using existing framework is better and would allow to concentrate development on what Hieroglyph3 has that GUI framework doesn't have: usng the GPU for computation and rendering.

In my opinion, there is room for a new framework in that area (GPU), not in the GUI area. There are already a few frameworks for GPU, but Hieroglyph3 could make his way there. This is particulary true if it can be integrated with existing mainstreet GUI framewaork such as MFC. This would be really useful for scientific, medical and industrial applications. Game market is already full of products and has a lot of big companies having millions of dollars available for developping new games.

Actually, for my current application which already exists without GPU use, I'm thinking of building a DLL with the image processing part and then use that DLL from the existing application, replacing the part which does the image processing. So basically in that scheme, I don't need a framework for the GUI part: it is already existing ! Of course, on the long term, the entire application is likely to be rewritten if the image processing part using GPU gives the expected results. Today, I'm at the "proof of concept" stage. I'm trying to find the shortest pathn yet realistic, to build a proof of concept application.

Nov 6, 2011 at 3:36 PM

In prior iterations of the engine, I actually added support for rendering with an MFC window.  Overall, it actually isn't too difficult to add support, so if you have a favorite framework (which are you using for your current app?) then we could fairly easily build the needed window information.  I haven't touched MFC in quite a while, but I could brush up on it and see what would be needed to whip up a window implementation...

Nov 6, 2011 at 3:40 PM

I'm using VCL, the framework in Embacadero C++ Builder and Delphi.

Nov 9, 2011 at 8:19 PM

I was reviewing the code necessary to allow the framework to operate within another windowing toolkit, and I realized that my usage of the event system in my application framework doesn't restrict someone from making their own app framework or even direct implementations within another windowing library.  It would simply require an appropriate window implementation in the host windowing toolkit, and as long as it could implement the same methods that the RenderWindow does then it should work perfectly fine.  The host application would need to call the appropriate API calls as seen in the Update method of the applications, and they could call them at whatever frequency they need to (i.e. continuously like my sample framework, or only in response to a paint message like you have suggested).

I have decided that I will implement an MFC sample application to demonstrate how this can be done.  I'll add that into the never ending queue of things to do :)

Nov 10, 2011 at 6:39 PM

Integrating with the window toolkit require some care from you - the designer - so that Hieroglyph 3 implements the require processing in well defined methods which will be called from the windowing toolkit. The existing Update method is a good example. The forthcomming Resize method is another one requiring careful implementation.

A MFC sample is for sure really welcome !

Nov 10, 2011 at 7:17 PM

I completely agree with your statements, and I think building the MFC sample will help to determine which methods are needed from my side.  After the MFC version, we'll see what other toolkits could make good targets...

By the way, the resize method is already implemented for the RenderApplication based samples - check out the base class (RenderApplication) for the first implementation, which can be specialized as needed in the subclasses.