Results 1 to 15 of 15

Thread: How to slow down a worker thread doing some scientific calculations?

  1. #1
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default How to slow down a worker thread doing some scientific calculations?

    One of the big features of my application is to run scientific simulations. For this, I have a worker thread where I do all the scientific calculations, and then I have the main thread that handles all the GUI stuff, including updating plots using the scientific data that has been calculated. Now, that data can tends to get calculated very quickly, meaning that the plots also get updated very quickly. I would therefore like to slow the calculations down (and, as a result, the updates to the plots too). Right now, my solution consists of using QWaitCondition::wait(), but the problem is that the time to wait can only be expressed in milliseconds, and that really makes things far too slow now. My understanding is that on Windows (I am targetting Windows, Linux and OS X), we can't go lower than 1 ms. So be it, I guess. Still, what other solution/approach/etc. would you recommend to achieve a sub-millisecond delay in a thread? Or am I simply out of luck here?...

    Cheers, Alan.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    This is a first - I have never heard of someone doing simulations who wanted to slow down the calculation :-)

    I think you are looking at this from the wrong perspective. The base problem is that your GUI can't keep up with the rate at which your simulation is producing results. So rather than making your simulation thread be in charge of when GUI updates occur, put the GUI in charge. Instead of letting whatever signal is coming from the thread trigger an immediate update, use it to simply set a flag that says an update is needed. The GUI can then check this flag whenever it is ready to do an update, and refresh your plots. It won't matter how fast your simulation runs, the GUI won't respond to it until it is ready.

    You might need to implement your own processEvents() loop where you check the update flag.

  3. The following user says thank you to d_stranz for this useful post:


  4. #3
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    More often than not, you don't want to slow down simulations, but for teaching or demonstration purposes it can be very useful indeed.

    Otherwise, my GUI definitely keeps up with the rate at which simulation data is being generated. In fact, the worker thread doesn't communicate with the GUI thread at all. Its only purpose is to generate simulation data, that's all. The GUI thread, on the other hand, does check whether new simulation data is available and, if so, then update its plots. The GUI thread will basically keep looking for new simulation data and when none is available anymore, then it will stop looking (until we run a new simulation). For this, I don't use signals/slots since it slows down things too much (yes, I want to slow things down, but only when I want them to be slowed down otherwise I want things to be as fast as possible... ). So, I am already kind of doing what you are suggesting, and I still want and need to be able to slow things down in my worker thread...

  5. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    OK, so if I understand you, what you are after is a way to run your simulation stepwise so you can display intermediate results for demonstration purposes?

    Some Googling turned up the SetWaitableTimer() Windows API call, which apparently can give you a timer with 100 ns resolution. See this MSDN entry. Also take a look at this.

    Unfortunately, there appears to be no portable cross-platform way to do this.

  6. #5
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    What I want and need to be able to do is to display the simulation data as if I was to display it in slow motion. Think of a movie that you play in slow motion. That's what I want to achieve.

    I will have a look at SetWaitableTimer() and see what I can do with it, if anything. Otherwise, I am starting to wonder whether the fact that my worker thread doesn't communicate with my GUI thread isn't actually a problem when I want my data to be displayed in slow motion. Hmm, I will need to look into that too.

  7. #6
    Join Date
    Oct 2013
    Posts
    18
    Qt products
    Qt4

    Default Re: How to slow down a worker thread doing some scientific calculations?


  8. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    Well, a movie typically runs at 30 fps, so that's 33 ms, well within the standard QTimer resolution. Updating faster than that won't be of much use since you can't visually process it even if the GUI can keep up.

    It probably makes sense to get your simulation thread talking to your GUI thread. Add start(), step(), and stop() slots to it, and connect the timeout() signal from a QTimer in the GUI thread to the step() slot. Add a stepDone() signal that the thread emits to let the GUI update the display and restart the timer.

    Set the timer as a single-shot to whatever interval makes sense (and this also gives you convenient control over the simulation from a slider in the GUI so you can implement variable slow motion). You can have an alternate entry point for the simulation when you want it to run at full speed without steps.

    So you basically have a signal / slot based handshake between the GUI and thread that runs when you want it to and is bypassed when you don't.

    ---
    Later: An alternative is to change the way your worker thread produces results. Let it run at full speed, and instead of producing a single final result, let it create a linked list or some other data structure that contains stepwise results. You can choose to play this back through the GUI by stepping through the list at whatever rate you want (or go backwards in time without having to re-run the simulation), or just display the final result by skipping to the end of the list.
    Last edited by d_stranz; 25th November 2013 at 23:11.

  9. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    Stupid question, but have you tried QThread::usleep()?

    Cheers,
    _

  10. #9
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    @qtbeginner0: that doesn't work under Windows.

    @d_stranz: I have tried CreateWaitableTimer()/SetWaitableTimer(), but it doesn't make any difference. I am still getting the same result as QWaitCondition::wait() or QThread::msleep(). So, it seems that I am really out of luck when it comes to Windows' time resolution which really seems to be one millisecond. I haven't yet had time to look into getting my worker thread to talk to my main thread (through the signal/slot mechanism), but it might be my only option left...

    @anda_skoa: yes, I have tried it, except that it doesn't work on Windows since it uses the ::Sleep() function which has a millisecond resolution. In fact, if you check qthread_win.cpp, you will see that QThread::usleep() is defined as ::Sleep((usecs/1000)+1)... !!

  11. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    I haven't yet had time to look into getting my worker thread to talk to my main thread (through the signal/slot mechanism), but it might be my only option left...
    What about my alternative suggestion of having your simulator write out a series of intermediate results as a list instead of just the final result? This doesn't require signals / slots or anything fancy, and is probably the least invasive as far as changes to your simulator code. If it already runs with some kind of time stepping (which is implied by your original question about how to slow it down), then you probably just need to write out a new link in the list at each step (or some multiple of steps, whatever makes sense). The simulator can then just run to completion, and hand its output over to the GUI side, just as it does now. No need for handshaking via signals and slots, no need to slow it down.

    Most of the changes come on the GUI side, which needs to be reworked to "play" the list of results. Despite this being my idea I think this has a lot of advantages. I've seen simulations of molecular motion where you can "rock" the molecule back and forth around some axis of rotation - in your case, this would amount to stepping backwards and forwards through the list of intermediate results. It also means you never have to re-run the simulation unless you change parameters - just keep replaying the same set of results. Likewise, you can vary the replay speed to get faster or slower slow motion.

  12. #11
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    Quote Originally Posted by d_stranz View Post
    What about my alternative suggestion of having your simulator write out a series of intermediate results as a list instead of just the final result? This doesn't require signals / slots or anything fancy, and is probably the least invasive as far as changes to your simulator code. If it already runs with some kind of time stepping (which is implied by your original question about how to slow it down), then you probably just need to write out a new link in the list at each step (or some multiple of steps, whatever makes sense). The simulator can then just run to completion, and hand its output over to the GUI side, just as it does now. No need for handshaking via signals and slots, no need to slow it down.
    I guess I could let the worker thread do its job as fast as possible (i.e. without taking into account the fact that the user might want a delay in the plotting of the results).

    However, this is not an option, because I use a progress bar to show the progress of the worker thread. Now, I agree that I could update the progress bar in a different way, i.e. by keeping track of how much has been plotted rather than how far down the simulation we are.

    Still, there is a more important reason why your approach is not an option, and it is the fact that the GUI allows the user to pause the simulation, modify some parameter values, and then resume the simulation. Now, as you can see, if I was to let the worker thread do its work and only plot the results when I want (so to speak), I would break an important feature of my application, and that is definitely not an option.

    So, as far as I am concerned, I have no other option but to slow down the worker thread itself.

  13. #12
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: How to slow down a worker thread doing some scientific calculations?

    Still, there is a more important reason why your approach is not an option, and it is the fact that the GUI allows the user to pause the simulation, modify some parameter values, and then resume the simulation.
    On "pause" signal you can tell your worker to stop as well as stop displaying the results in gui. Results that are still in the "todo" list and were not yet displayed in gui could be simply discarded at this point (if you change the processing parameters).
    I agree with d_stranz, some time ago I was working on very similar problem with live data processed / generated faster than the gui refresh rate. In general, the final implementation contains a list of intermediate results, updated very frequently in the worker thread, and displayed with desired speed in the gui thread (or played backwards, whatever, if you have a list of intermediate results with "timestamps" you can do whatever you want with them).

  14. #13
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    Quote Originally Posted by stampede View Post
    On "pause" signal you can tell your worker to stop as well as stop displaying the results in gui. Results that are still in the "todo" list and were not yet displayed in gui could be simply discarded at this point (if you change the processing parameters).
    Yes, I did think of that, it's just that it would require some work on both my GUI and worker threads while it wouldn't require any work if I could, somehow, slow down my worker thread as such. This being said, it might be my only option here...

  15. #14
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    Hope you don't mind us beating up on you but you can still accomplish what you want without inserting delays into the simulation.

    If you can currently pause your simulation, change parameters, and then resume it again, I assume you have some concept of "current state of the simulation using parameters {x}".

    So, back to my proposal where the simulation runs at full speed to completion and saves a list of results: A relatively easy way to implement the pause / change / resume feature would be to not only output the intermediate results at each time step, but also output whatever state variables / parameter values there are at that step. When the user pauses the playback, edits parameters, and resumes, you reload the simulation with the current state values and new parameters, discard the rest of the results list, then let the simulation run to completion from that point forward.

    Another benefit: If simulation always runs to completion, you have the option of saving the whole list to a file. The user can then step backwards to some point, change parameters, and let it run again. Now you have a way to directly compare two versions of the simulation side-by-side to see the effect of the parameter change. Or you can reload a saved simulation to study it again, without having to recompute it. If you really decouple the results viewing from the results generation and save some version information in the results, now you have a way to compare the effects of algorithmic changes as well as parameter changes.
    Last edited by d_stranz; 5th December 2013 at 00:36.

  16. #15
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to slow down a worker thread doing some scientific calculations?

    Quote Originally Posted by d_stranz View Post
    Hope you don't mind us beating up on you but you can still accomplish what you want without inserting delays into the simulation.

    If you can currently pause your simulation, change parameters, and then resume it again, I assume you have some concept of "current state of the simulation using parameters {x}".

    So, back to my proposal where the simulation runs at full speed to completion and saves a list of results: A relatively easy way to implement the pause / change / resume feature would be to not only output the intermediate results at each time step, but also output whatever state variables / parameter values there are at that step. When the user pauses the playback, edits parameters, and resumes, you reload the simulation with the current state values and new parameters, discard the rest of the results list, then let the simulation run to completion from that point forward.

    Another benefit: If simulation always runs to completion, you have the option of saving the whole list to a file. The user can then step backwards to some point, change parameters, and let it run again. Now you have a way to directly compare two versions of the simulation side-by-side to see the effect of the parameter change. Or you can reload a saved simulation to study it again, without having to recompute it. If you really decouple the results viewing from the results generation and save some version information in the results, now you have a way to compare the effects of algorithmic changes as well as parameter changes.
    Thanks a lot d_stranz, you make some good points. I particularly like the possible benefit of comparing two versions of a simulation side-by-side. Possible because it assumes that the 'default' simulation would have time to finish, for which there is no guarantee whatsoever.

    Anyway, I have to be pragmatic. My simulation code has been stable for months. Yet, from what I can tell, to implement your suggestion would require quite a bit of work on my end. So, the simplest solution for me would be to slow down my worker thread: minimal work on my end, no additional testing required, etc.

    So... this is what I did yesterday afternoon. I simply added a loop that does nothing for a given number of times (to make the worker thread more or less slow). I genuinely wish there was a better way to slow down my worker thread, but at least it was very simple to implement, didn't require me having to rework my GUI thread, retest things, etc. and, more importantly, it does exactly what I want. Sure, a loop that does nothing will use the CPU for... nothing, but then again it's a worker thread, so I am 'fine' with it being always busy while it's actually running a simulation.

Similar Threads

  1. Replies: 4
    Last Post: 17th October 2013, 11:12
  2. QAxObject worker thread
    By semajnosnibor in forum Qt Programming
    Replies: 2
    Last Post: 21st January 2012, 16:10
  3. Worker thread
    By doggrant in forum Newbie
    Replies: 4
    Last Post: 3rd November 2009, 15:49
  4. Worker thread problem
    By hkvm in forum Qt Programming
    Replies: 4
    Last Post: 6th September 2009, 20:12
  5. Main thread - worker thread communication.
    By kikapu in forum Newbie
    Replies: 25
    Last Post: 23rd May 2007, 22:09

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.