How to deal with unresponsive UI in high-volume model update scenarios - c++

We're using Qt 4.8.2, and we have a model/view design (subclassed QAbstractItemModel and QTreeview, specifically). The model/treeview follows the typical philosophy where the view drives the model - we don't populate the model until the user expands the corresponding treeview nodes.
Once a node has been expanded & data is visible, it is subject to display updates that occur in worker (non-UI) threads. Right now, when a worker thread produces a change that may affect the treeview, it emits a "change" signal, which maps to a slot in our model.
The problem is that these change signals can be emitted with great frequency (say, 1500 events over a second), sometimes, but they may apply to what the treeview currently displays (and can therefore be ignored). When this happens, the UI thread becomes unresponsive as (I presume) the signals all queue up and the UI thread has to deal with them before it can resume responding to user interaction.
The time it takes to respond to a change signal is very small, but it appears that the UI thread only "eats" the signals after a small delay - presumably to avoid excessive updating resulting in screen flicker or other annoyances.
The result is that the UI remains frozen for 5 or 6 seconds, with very low CPU activity during this time (presumably because the signals are coming in fast enough the handler is still waiting for break in the action); once all the signals are queued up, the thread finally consumes the work in the queue and resolves it in a few milliseconds.
I have several thoughts on this:
Is there some setting such that I can increase the aggressiveness by which the UI thread handles incoming signals?
Is it feasible at all to manage the updates of the model in a separate thread? My instinct is to say no - it would seem the Qt machinery is too dependent on exclusive ownership of the model, and putting the appropriate lock protection around its access would be complicated and violate the whole point of the slot/signal paradigm.
I can think up more complex schemes to deal with this signals in a secondary thread; for example, the UI could maintain a separate multithread-visible (non-model) data structure that could be queried to determine whether a change signal needed to be sent. Similarly, I could maintain a separate queue that the worker threads use, where I could batch up change events into a single signal (which I could deliver no more than twice a second, for example). But these methods strike me as a bit byzantine for a problem that I assume must not be totally uncommon in the domain of Qt UI programming.

We had a similar application with large updates to underlying data. The question comes down to:
1500 updates per second will result in how many changes in the GUI?
If the answer is there will be less than 6 changes, then the model should only emit 6 data changes per second. If this is the case, when underlying data changed, check if this change will change the GUI or not, only emit data changed signal from model when necessary.
If the answer is there will be more than 6 gui changes per second, the answer we have is no human being can see more then 3 changes per second. The underlying data change should not update GUI at all. Use a 250 milli second timer, in the timer event, check the cells needs to be updated, and update them.

Related

Updating QML from highly dynamic C++ data model: Timer vs Property binding

Assume a C++ business model which is potentially changing its underlying data very quickly (let's say up to 1000 Hz).
In my specific case, this would be a wrapper around a network data callback mechanism (a ROS-subscriber to be more precise) running in its own thread. Think of the data as some sensor reading. Further assume that we are dealing with simple data, e.g. a single double value or a string in the worst case.
What would be the best way to visualize such data in a QML component? Best here is with respect to being gentle with resources, minimizing the delay between model state and view, and being as clean code as possible?
I came up with the following options:
Bind the data as property of the model to the view, and emit a dataChanged() signal on every update of the data:
Pro: Elegant code, lowest resource usage in case of low data update rates.
Con: High signal frequency will spam the GUI and maximize resource utilization, potentially rendering the system unresponsive.
Use a QML-Timer and poll the model at a specific interval (e.g. 10 - 60 Hz):
Pro: Upper limit on resource utilization, steady rate
Con: Timer itself consumes resources; not as elegant as data binding; if data generation/callback rate is lower than timer rate, unnecessary polling calls have to be made.
Use data binding as in 1. but throttle the signal emitting frequency inside the C++ model using a QTimer (or another timer like boost's), i.e., only emit the dataChanged() signal at specific intervals:
Pro: Same as 2.
Con: Same as 2.
Combine Timer from 3. with some kind of check whether the data actually changed, prior to emitting the signal, thus avoiding unnecessary signal emitting if data has not changed:
Pro: Same as 3.
Con: same as 3. but even less elegant; increased risk to induce a bug because logic is more complicated; model is harder to reuse as the data changed check highly depends on the nature of the data
Did I miss an option (besides not producing so much data in the first place)? What would be your choice or the most QT/QML way of realizing this?
First of all, have you established that there is a performance problem?
I mean granted, 1000 updates per second is plenty, but is this likely to force GUI updates a 1000 times a second? Or maybe the GUI only updates when a new frame is rendered? Any remotely sane GUI framework would to exactly that. Even if your data changes a gazzilion times per second, GUI changes will only be reflected at the frame rate the GUI is being rendered in.
That being said, you could work to reduce the strain on the backend. A typical "convenience" implementation would burden the system, and even if any contemporary platform that Qt supports could handle 1000 Hz for an object or two, if those are many, then you should work to reduce that. And even if not directly detrimental to system performance, efficiency is always nice as long as it doesn't come at a too high cost development wise.
I would not suggest to directly update data using a property or model interface, as that would flood with signal notifications. You should handle the underlying data updates silently on the low level, and only periodically inform the property or model interface of the changes.
If your update is continuous, just set a timer, 30 Hz or even less outta be OK if a human is looking at it.
If it is not, you could use a "dirty" flag. When data changes, set the flag and start the update timer as a single shot, when the timer triggers and notifies the update, it clears the flag and suspends. This way you avoid running the timer without any updates being necessary.

Race conditions with JavaFX worker threads and PropertyChangeSupport

I am working on a system that uses multiple worker threads inside of a JavaFX Task. The Callable objects on these threads inside of the Task use PropertyChangeSupport to communicate certain state change information back to listeners (e.g. intermediate results). I am using PropertyChangeListeners to monitor these changes and create derivative objects off of them that are accessed by other objects. Once the Task is finished I am using JavaFX to display information, some of which is gleaned from the PropertyChange events that are emitted.
My question is: is there a potential for a race condition between the Task finishing and the PropertyChangeEvents getting processed (which I would assume would happen on the JavaFX application thread, but not completely sure).
As a concrete example, consider an image that is getting split into chunks for processing in multiple steps. At each step, an intermediate image is generated and a propertyChange event is getting fired for that intermediate image. At the end of processing, I want to be able to display the final image as well as all the images generated in the meantime in a JavaFX Scene. Will the propertyChange events all get processed before the FX thread repaints/refreshes?
I realize that the JavaFX documentation has an example with the Task api doc discussing returning intermediate results (JavaFX Task API Documentation). That example uses the JavaFX Observable* objects. I would think that PropertyChangeEvents would run on the same thread similar to the FX observable object and as such there should not be a race condition between finishing a non-FX thread and getting results on the FX thread, but thought I would see if there is anything I might not be thinking of.
Thanks in advance for any discussion or thoughts.
Chooks
You are correct that PropertyChangeEvents will run on the same thread as the FX observable objects. This is, however, a different thread from the Task itself.
However, you don't have any guarantee that all of the propertyChange events will get processed before the FX thread repaints/refreshes. In fact, various parts of the display could get repainted multiple times between different propertyChange events, depending on how long they take and the specific timing involved. Also, other FX events could be interspersed between the propertyChange events and the repainting as well. However, you should be guaranteed that any UI elements updated by any given propertyChange event will be eventually repainted at some time after they are updated. So the display will eventually "catch up" to any changes that are made by your propertyChange handlers, and will eventually repaint any areas that were changed.

Some questions on Multithreading and Background worker threads in windows form

I have encountered the need to use multithreading in my windows form GUI application using C++. From my research on the topic it seems background worker threads are the way to go for my purposes. According to example code I have
System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e)
{
BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);
e->Result = SomeCPUHungryFunction( safe_cast<Int32>(e->Argument), worker, e );
}
However there are a few things I need to get straight and figure out
Will a background worker thread make my multithreading life easier?
Why do I need e->Result?
What are the arguments passed into the backgroundWorker1_DoWork function for?
What is the purpose of the parameter safe_cast(e->Argument)?
What things should I do in my CPUHungryFunction()?
What if my CPUHungryFunction() has a while loop that loops indefinitely?
Do I have control over the processor time my worker thread gets?
Can more specifically control the number of times the loop loops within a set period? I don’t want to be using up cpu looping 1000s of times a second when I only need to loop 30 times a second.
*Is it necessary to control the rate at which the GUI is updated?
Will a background worker thread make my multithreading life easier?
Yes, very much so. It helps you deal with the fact that you cannot update the UI from a worker thread. Particularly the ProgressChanged event lets you show progress and the RunWorkerCompleted event lets you use the results of the worker thread to update the UI without you having to deal with the cross-threading problem.
Why do I need e->Result?
To pass back the result of the work you did to the UI thread. You get the value back in your RunWorkerCompleted event handler, e->Result property. From which you then update the UI with the result.
What are the arguments passed into the function for?
To tell the worker thread what to do, it is optional. Otherwise identical to passing arguments to any method, just more awkward since you don't get to chose the arguments. You typically pass some kind of value from your UI for example, use a little helper class if you need to pass more than one. Always favor this over trying to obtain UI values in the worker, that's very troublesome.
What things should I do in my CPUHungryFunction()?
Burn CPU cycles of course. Or in general do something that takes a long time, like a dbase query. Which doesn't burn CPU cycles but takes too long to allow the UI thread to go dead while waiting for the result. Roughly, whenever you need to do something that takes more than a second then you should execute it on a worker thread instead of the UI thread.
What if my CPUHungryFunction() has a while loop that loops indefinitely?
Then your worker never completes and never produces a result. This may be useful but it isn't common. You would not typically use a BGW for this, just a regular Thread that has its IsBackground property set to true.
Do I have control over the processor time my worker thread gets?
You have some by artificially slowing it down by calling Thread.Sleep(). This is not a common thing to do, the point of starting a worker thread is to do work. A thread that sleeps is using an expensive resource in a non-productive way.
Can more specifically control the number of times the loop loops within a set period? I don’t want to be using up cpu looping 1000s of times a second when I only need to loop 30 times a second.
Same as above, you'd have to sleep. Do so by executing the loop 30 times and then sleep for a second.
Is it necessary to control the rate at which the GUI is updated?
Yes, that's very important. ReportProgress() can be a fire-hose, generating many thousands of UI updates per second. You can easily get into a problem with this when the UI thread just can't keep up with that rate. You'll notice, the UI thread stops taking care of its regular duties, like painting the UI and responding to input. Because it keeps having to deal with another invoke request to run the ProgressChanged event handler. The side-effect is that the UI looks frozen, you've got the exact problem back you were trying to solve with a worker. It isn't actually frozen, it just looks that way, it is still running the event handler. But your user won't see the difference.
The one thing to keep in mind is that ReportProgress() only needs to keep human eyes happy. Which cannot see updates that happen more frequently than 20 times per second. Beyond that, it just turns into an unreadable blur. So don't waste time on UI updates that just are not useful anyway. You'll automatically also avoid the fire-hose problem. Tuning the update rate is something you have to program, it isn't built into BGW.
I will try to answer you question by question
Yes
DoWork is a void method (and need to be so). Also DoWork executes
in a different thread from the calling one, so you need to have a
way to return something to the calling thread. The e->Result
parameter will be passed to the RunWorkerCompleted event inside
the RunWorkerCompletedEventArgs
The sender argument is the backgroundworker itself that you can use
to raise events for the UI thread, the DoWorkEventArgs eventually
contains parameters passed from the calling thread (the one who has
called RunWorkerAsync(Object))
Whatever you have need to do. Paying attention to the userinterface
elements that are not accessible from the DoWork thread. Usually, one
calculate the percentage of work done and update the UI (a progress
bar or something alike) and call ReportProgress to communicate with
the UI thread. (Need to have WorkerReportProgress property set to
True)
Nothing runs indefinitely. You can always unplug the cord.
Seriously, it is just another thread, the OS takes care of it and
destroys everything when your app ends.
Not sure what do you mean with this, but it is probably related
to the next question
You can use the Thread.Sleep or Thread.Join methods to release the
CPU time after one loop. The exact timing to sleep should be fine
tuned depending on what you are doing, the workload of the current
system and the raw speed of your processor
Please refer to MSDN docs on BackgroundWorker and Thread classes

Emitting a signal to one object in a set dynamically

I have a situation where I have a single Emitter object and a set of Receivers. The receivers are of the same class, and actually represent a set of devices of the same type. I'm using the Qt framework.
The Emitter itself first gets a signal asking for information from one of the devices.
In the corresponding slot, the Emitter has to check to see which of the Receivers are 'ready', and then send its own signal to request data to one of the devices (whichever is ready first).
The Emitter receives signals very quickly, on the order of milliseconds. There are three ways I can think of safely requesting data from only one of the devices (the devices live in their own threads, so I need a thread-safe mechanism). The number of devices isn't static, and can change. The total number of devices is quite small (definitely under 5-6).
1) Connect to all the devices when they are added or removed. Emit the one request and have the devices objects themselves filter out whether the request is for them using some specific device tag. This method is nice because the request slot where the check occurs will execute in a dedicated thread's context, but wasteful as the number of devices go up.
2) Connect and disconnect from the object within the Emitter on the fly when it's necessary to send a request.
3) Use QMetaObject::invokeMethod() when its necessary to send a request.
Performance is important. Does anyone know which method is the 'best', or if there's a better one altogether?
Regards
Pris
Note: To clarify: Emitter gets a signal from the application, to get info by querying the device. Crazy ASCII art go:
(app)<---->(emitter)<------>(receivers)<--|-->physical devices
Based on the information you have provided I would still recommend a Reactor implementation. If you don't use ACE then you can implement your own. The basic architecture is as follows:
use select to wake up when signal or data is received from the App.
If there is a socket ready on the sending list then you just pick one and send it data
When data is sent the Receiver removes itself from the set of sockets/handlers that are available
When data is processed the Reciever re-registers itself to the list of available recipients.
The reason I suggested ACE is because it has one of the simplest to use implementations of the Reactor pattern.
I'm amusing here this is multi thread environment.
If you are restricted to Qt signal / slot system between then the answer for your specific questions:
1) is definitely not the way to go. On an emit from the Emitter a total number of events equal to the number of Receivers will be queued for the thread(s) event loops of the devices, then the same number of slot calls will occur once the thread(s) reach those event. Even if most of the lost just if(id!=m_id) return; on their first line, its a significant amount of things going on in the core of Qt. Place a breakpoint in one of your slots that is evoked by a Qt::QueuedConnection signal and validate this looking at the actual stack trace. Its usually at least 4 call deep from the xyEventLoop::processEvents(...), so "just returning" is definitely not "free" in terms of time.
2) Not sure how Qt's inner implementation actually is, but from what I know connecting and disconnecting most likely include inserting and removing the sender and receiver into some lists, which are most likely accessed with QMutex locking. - might also be "expensive" time-wise, and rapidly connecting and disconnecting is definitely not a best practice.
3) Probably the least "expensive time-wise" solution you can find that is still using Qt's singnal-slot system.
optionally) Take a look at QSignalMapper. It is designed exactly for what you planned to do in option 1).
There are more optimal solutions to communicate between your Emitter and Receivers, but as a best practice I'd first choose the option that is most easy to use and fast to implement, yet has a chance of being fast enough run-time (that is option 3). ). Then, when its done, see if it meets your performance requirements. If it does not, and only then, consider using shared memory with mutexes in a data provider - data consumer architecture (Emitter thread rapidly post request data in a circular list, while the Receiver thread(s) reads them whenever have time, then post results back a similar way, while the Emitter thread constantly polls for done results.)

Creating a thread for a database in Qt: a reasonnable design or nonsense?

the application I'm trying to design with Qt is quite data intensive; it is essentially a database. I'm looking for a design that would allow me to keep the UI reactive. My guess is I should keep only the UI in the main thread and create a thread for the database.
However:
- creating a database object inheriting from QThread doesn't seem to be a natural design (what would run() be? )
- I assume I would need to use signals and slots for UI / core interaction; yet this feature seem to be relatively recent in Qt, so I'm wondering if my "design" is wrong.
- QObject descendants are apparently designed to live in the thread in which they were created, so I'm concerned the communication of models (from the database thread) to the UI thread will be problematic.
Thanks for your comments.
You might consider using QtConcurrent::run(). You'll pass in the function you want. It'll spool off a thread to run the function and give you a QFuture that you can use to get the eventual result. You could poll the QFuture to see if it isFinished(). Better, however, may be to use QFutureWatcher which watches the QFuture for you and emits a signal when it's done. See the example code blurb in QFutureWatcher.
Well, I think creating a separate thread for the DB stuff is a good idea... but I would suggest that you only make 1 thread for the DB stuff (not 2, 4, or more). The reason is that unless you are an expert at DB concurrency issues and the locking mechanisms of your DB, things will get complicated.
The thing is that you should not have any other threads mixed with code that has gui or in main of a gui project because any blocking will freeze the GUI as well. So as long as you make a separate DB handler class and thread that, I think you should be OK.
Once I asked that same question "Is this design good?" (after detail explanation), the answer I got is "when doing a design of something, only the sky is the limit".
If you think threads might cause problems, then you should start processes, instead of threads.
Don't forget that you can always block and disable widgets when doing some intensive computation (a famous hourglass icon).
Signals and slots are implementation of observer pattern. In my opinion, it is one of the very useful design patterns. It allows you to easily break dependencies. If you don't like signal slots, then take a look into events.
EDIT
For processes, you can use IPC (inter process communication) - not necessarily using stdout. There are pipes, shared memory and messages.
As for freezing the widgets, you can disable them, or the mouse (turning it into a hourglass) when your application is doing some computation intensive operation, and when you think the GUI might become unresponsive. Or, you can show the invisible widget covering your GUI and change the mouse into the hourglass. This way the mouse events would go to the invisible widget and ignored. You can also add "please wait" box on top of it.
You didn't say what exactly you are trying to achieve. Maybe there is a better way.