Quote:Original post by B_old
If the first (or any) thread gets all the heftiest tasks, the other threads will have to wait for it?
Yes, that's definitely a worry. But see my comment about k*N chunks. Also, now's a good time to look up work stealing :)
It all comes down to balancing the costs of:
- task creation
- sequence iteration
- task submission
- task execution
- per-task processing overhead
Different strategies will work better for different kinds of work. If you know that some tasks will take much more time than others, then small range-chunk sizes are certainly something to try.
Quote:
My idea is this: I have an object that provides an interface to fetch tasks. I pass that object to the thread pool and the threads start fetching tasks and processing them. Is that what you mean by the idea in my head? :)
More or less :)
Quote:I like the idea of a pool as well, I just needed a way to ensure that different threads never fetch the same task.
Express it as an algorithm and let it worry about that e.g. parallel_for_each().
The parallel_for_each function we use at work looks something like this (pseudo code):
// Ignoring any special cases for non-random-access iteratorstemplate< /* blah */ >void parallel_for_each(thread_pool threads, RAIter begin, RAIter end, const UnaryFunctor &f, std::size_t granularity = deduce_granularity){ task_pool tasks; range_chunker rc(begin, end, threads.size(), granularity); while ((chunk = rc.next()) tasks.add(make_task(chunk.begin, chunk.end, f)); future<void> completion = threads.take(tasks); completion.check();}
The algorithm itself ensures that tasks are distributed correctly. Surely you don't want to have to do that manually every time?