Keep UI responsive when CPU load is 100%



  • I have a multi-threaded Qt application. Worker threads received data and process them as fast as possible.

    Nevertheless, when the amount of data is too big for the machine, the CPU is used at 100%, and the Qt UI become lagging. It can takes 5 seconds to get a button click performed.

    I tried to set the workers threads priority to QThread::LowestPriority, but it is changing nothing.

    Is there any easy way to tell to my program to keep some CPU load available for the UI (and the OS). In fact, i want the worker threads working fully only if there is no other tasks to do on the computer.

    Thank you for your help.



  • for my perception during the Mouse events you may pause or slow down (by increasing the delay inside thread) the thread, by this you may have enough CPU cycle for the UI response.
    it is always better to give some delay inside thread instead of continuous loop.

    @
    {
    //process some data
    sleep(10);
    }
    @

    instead of--
    @
    {
    //process some data
    ......................
    }@



  • Are you sure all your objects are in the thread you think they are? Could it be that your TCP handing is in the main thread after all, thus blocking GUI handling with both TCP work and the work to do the cross-thread signalling needed?



  • Using just sleep() function will still block UI, you need to process pending events to:

    @
    {
    //process some data
    QApplication::processEvents(QEventLoop::AllEvents);
    sleep(10);

    }@



  • [quote author="AcerExtensa" date="1342434829"]Using just sleep() function will still block UI, you need to process pending events to:

    @
    {
    //process some data
    QApplication::processEvents(QEventLoop::AllEvents);
    sleep(10);

    }
    @
    [/quote]

    We're talking multi-threading here, so no, sleep will not block your entire application.



  • right, sorry...



  • Thank you for all you're answer.

    Actually, I would like to not use a sleep function because my application is rendering frame in multiple view at same time (each thread is one view). The GUI is Qt but the frame rendering is done by DirectX in the worker thread. This is done to allow the Qt UI Thread to only manage the Qt's GUI events. So i want the frame rendering to be fast as it is possible to keep the original FPS (when it's possible), and sleep (10) can disturb the rendering.

    By the way, normally my worker thread doesn't use any signal, the thread is a QThread but it doesn't use any other Qt Object (in fact only QSharedPointer).



  • You'll have to decide between a responsive UI and maxing out the CPU with your worker threads, to a point.

    If 10 milliseconds sounds too long, you might take a look at QThread::usleep()

    And by the way: If sleep(10) can really disturb the rendering (and not only delay it slightly), then you are in trouble. Because you don't know how long it will take for the context to return to any specific worker thread. It might be way beyond 10 milliseconds - you just don't know. No logic in your code can assumes there's no break in execution longer than that.



  • So i tried the sleep this solution, but it doesn't work. I think it's because if i have for example 4 thread, they basically never fall in sleep at the same time, so the CPU load is always saturated.

    Of course if i use sleep(500), ok it works, but the FPS fall to 2 FPS (to small). Using sleep(10) is not enough, to give time to the UI thread, and if i want to keep at least 24 FPS (i can't use more that sleep 30).

    Really no way to tell the OS that some thread are secondary and you have to give time to it, only if there is nothing else to do?



  • Actually you not told us how ur application works, as if u r using DirectX, may be it is SW rendering no gpu, check ot first. Because if app is running as sw rendered then it will eat up ur cpu.



  • Hi, thank you all for your help! I found the solution. Sometime the problem is between the screen and the chair. It was just a bug in my application.

    I investigated why thread priority was not working, and using process explorer i found that my priority wasn't really set. I was just an hidden line of code that was changing the priority. So setting the thread priority to low work very well.

    My problem is solved!



  • You should also add a @QThread::yieldCurrentThread()@ in the inner-loops of the threads that perform the background operations. This will give the OS a hint that it is a good time to reschedule CPU time among all the threads.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.