How to use full processing power available to do calculations?
-
Hi, I am working on a plotting application. In a single application, there are multiple plot areas and each of these plot areas has multiple line plots. Currently, I am creating a single
QThread
for each of the plot areas by subclassingQObject
and usingmoveTothread()
function to move these plot areas in their own thread where I perform the calculations to generate the line plots associated with each plot area. However, sometimes in my application, there is just one plot area that has many line plots, this makes using a single thread associated with that plot area to do all calculations sequentially highly inefficient as any extra threads available to my application is just sitting idle. I looked at Multithreading Technologies documentation and I am unable to figure out which approach to use to further distribute the calculation of each line plot from each plot area to as many threads as possible. My requirements are:- Distribute processing as much as possible
- Be able to cancel long-running calculation in between
- Do the calculation without blocking the GUI (the main reason why each plot area is in its own thread)
Because of the first and second requirements above, I cannot use
QtConcurrent::run()
as it uses a single thread and cannot be paused/resumed/canceled. So, I am left with two choices:QtConcurrent::mapped()
QThreadPool
SpecificallyQThreadPool::globalInstance()
as i do not want to manage the thredpool myself (want to giveQt
andOS
it's own space to manage threads without me being involved)
Regarding the above two choices, I have a few questions which I was unable to find answer to anywhere else:
- If I use more threads by using
QtConcurrent::mapped()
orQThreadPool
from inside a non-GUI thread, will it use this non-GUI calling thread as well? To make my point more clear: Let's say I create a thread calledA
and based on the number of cores my CPU has I have threadB
,C
andD
available. After my threadA
calls eitherQtConcurrent::mapped()
orQThreadPool
to start the calculation it has nothing more to do till the calculation finishes, so will it wait idle while my calculations are running in other threads or willQtConcurrent::mapped()
orQThreadPool
include threadA
along withB
,C
andD
to do the calculations? - Is there any way I could run a single loop (major loop of my calculation) in multiple threads with different data sets without using
QtConcurrent::run()
?QtConcurrent::mapped()
will not work as it has requirements that there should be a return type which is not always the case with my calculations.QThreadPool
,QRunnable
and especiallyQThreadPool::globalInstance()
documentation is not enough for me to make this judgement. - Finally, is there a better/simpler approach to solving this problem? The outline of my main loop to calculate final line plots is as follows:
for(int ii = 0; ii < vectorData.length(); ++ii) // vectorData is QVector<QVector<double>>, there is a single vectorData for each plot area { for(int jj = 0; jj < vectorData[ii].length(); ++jj) { // Do the calculation to find raw values related to each x-pixel and store it in a vector } for(...) // This for loop depends on raw values calculated above { // Place the raw values calculated above to correct the y-pixel value // two inner for loops are needed as placing any raw values to correct y-pixel value requires knowledge of the next raw value } }
If I could run just the above loop in a distributed manner in as many processor cores as available without blocking the GUI and with an ability to abort the calculation in between that would be ideal.
NOTE: I have placed the same question in Stack Overflow as well.
-
-
@fcarney Hi thanks for pointing it out. I understand what you are saying, but this question is not about the help with the code but rather about the general direction of what to choose as I find the amount of documentation about
QtConcurrent
andQThreadPool
to be quite incomplete. -
When I get stuck I build something. See what works. I have a repo dedicated to things I test out at work. Then when I figure it out I have a huge collection of examples of how to do things (and someones how not to do). I get you are at the middle point, not sure where to start. You may end up having to do a process of elimination.
-
@CJha said in How to use full processing power available to do calculations?:
- If I use more threads by using
QtConcurrent::mapped()
orQThreadPool
from inside a non-GUI thread, will it use this non-GUI calling thread as well? To make my point more clear: Let's say I create a thread calledA
and based on the number of cores my CPU has I have threadB
,C
andD
available. After my threadA
calls eitherQtConcurrent::mapped()
orQThreadPool
to start the calculation it has nothing more to do till the calculation finishes, so will it wait idle while my calculations are running in other threads or willQtConcurrent::mapped()
orQThreadPool
include threadA
along withB
,C
andD
to do the calculations?
We need to know: How do you create thread
A
?QtConcurrent
uses the globalQThreadPool
behind the scenes. If threadA
is not part of the pool, then it won't be used by the pool to do calculations when it is idle.- Is there any way I could run a single loop (major loop of my calculation) in multiple threads with different data sets without using
QtConcurrent::run()
?QtConcurrent::mapped()
will not work as it has requirements that there should be a return type which is not always the case with my calculations.QThreadPool
,QRunnable
and especiallyQThreadPool::globalInstance()
documentation is not enough for me to make this judgement.
QtConcurrent::map()
(notmapped()
!) does not return any values. You can interface with it usingQFuture<void>
.See https://doc.qt.io/qt-5/qtconcurrentmap.html#concurrent-map
- Finally, is there a better/simpler approach to solving this problem?
Experiment with
QtConcurrent::map()
and see if it suits your application.NOTE: I have placed the same question in Stack Overflow as well.
As a courtesy to other users, please link your duplicate questions to each other. This way, people can see if your question has been resolved and get the answer too
- If I use more threads by using