@JonB said in Is QtConcurrent suitable for this concurrent/parallel algorithm?:
@JKSH said in Is QtConcurrent suitable for this concurrent/parallel algorithm?:
Then, apply QtConcurrent::map() to your QList<Range>. This is the idiomatic way^ to express your algorithm above.
We shall see. For now I am creating QtConcurrent::run()s for each available core, per my approach earlier, passing in parameters to each one for what "range" to test.... When that's working/timed, I might compare against the list approach.
To clarify: What I described does EXACTLY the same thing as your multiple QtConcurrent::run() calls, so I'd expect the timing to be the same.
It was to show you how to use QtConcurrent::mapped() to run the algorithm that you described (my apologies, my previous post erroneously said map() instead of mapped()). The main difference is that you end up with a single QFuture instead of one QFuture per thread:
struct Range {
long start;
long limit;
long step;
};
bool threadFunc(const Range &range)
{
for (long divisor = range.start; divisor <= range.limit; divisor += range.step)
if (dividend % divisor == 0)
return false;
return true;
}
// ### Set up and run your threads
int threads = available_threads(); // maybe 8?
QList<Range> ranges;
for (int thread = 0; thread < threads; thread++)
ranges << Range{2+thread, limit, threads}; // Or `Range{3+thread, limit, 2*threads};` if you've already tested for evenness earlier
QFuture<bool> future = QtConcurrent::mapped(ranges, threadFunc);
// ### Set up your results monitor
auto watcher = new QFutureWatcher<bool>(someParent);
QObject::connect(watcher, &QFutureWatcher<bool>::resultReadyAt, qApp, [watcher](int index)
{
if (!watcher->resultAt(index))
qDebug() << "Thread" << index << "found a factor";
});
watcher->setFuture(future);
What we are all agreeing, apparently, is not to do the naïve "create a thread for each test division (not with a loop to test a bunch of them)", and let QtConcurrent figure out threads & pool for it. Which to me is the "logical" way a noob might approach it, but I assume grossly slow.
Indeed. I haven't benchmarked, but I'd expect the cost of setting up a thread to be comparable to the cost of doing a single division in that thread.
Once an instance of your threadFunc() starts running, it normally can't be terminated before completion (in contrast, QThread offers a terminate() function)...
Ah, OK again. Yes, surprises me if basic QThread does allow forceful terminate.
Thread termination is a foot-gun. It's safe here because you're only reading integers and writing Booleans.