5
votes

I need to implement a thread pool executor for generic tasks. My idea is to use OpenMP for thread management. The problem is that I'm not familar yet with OpenMP..

I tried to find an existing implementation of the generic ThreadPool with OpenMP, but I haven't find one so far. What I would like to have in the end is something very similar to java.util.concurrent.ThreadPoolExecutor:

template <typename Return, typename Task>
class ThreadPoolExecutor
{
public:
    ThreadPoolExecutor(int threadCount);

    // asyncronous invoke
    boost::unique_future<Return> submit(const TaskPtr & task);

    // blocking call
    std::vector<Return> invokeAll(const std::vector<TaskPtr> & tasks)
    {
        // submit all tasks + wait for completion
        #pragma omp parallel default(shared)
        {
            // call tasks here
        }
    }
};

I have several questions about this approach:

  1. Is there existing implementation of thread pool with OpenMP for C++? [I know I can implement threadpool with boost::asio::io_service, but I would prefer not depend on it]

  2. With my design - how can we guarantee that the OpenMP threads will be 'owned' by the concrete ThreadPoolExecutor instance? They should not be static for all instances.

Thank you for any advice & constructive critics of this approach & proposals of other implementations.

1
For your second question: You can't. Management of the openmp threads is the job of the implementation. As a sidenote: Why do you need an implementation based on openmp? Have you looked at the (not yet official) boost threadpool? Or maybe Intel TBB? - Grizzly
I'm afraid OpenMP is not suited for such a task... - Tudor
@Grizzly: Thanks. I'm aware of TBB and boost threadpool. But my project is the library for other developers and I can't easily introduce dependencies on those products. OpenMP would be nice because it does not require additional dependencies. - nogard
Unfortunately there's no way to guarantee that a certain object is self-contained and won't share threads with other OpenMP sections. OpenMP was not really designed with OOP in mind. - Tudor
@nogard: As mentioned openmp is not really god for this task (you can't control the threads and have no option but to block on invocation). How about basing a threadpool on boost::thread (since your code already contains boost::unique_future I assume that this depency would be ok) or c++11 std::thread? Or even pthreads if nothing else is availible (wrapping those into a std::thread like interface is pretty straight forward). - Grizzly

1 Answers

2
votes

Just to sum up: as described in the comments OpenMP is not an option for implementing generic thread pool or executor, because:

  1. OpenMP is strictly a fork/join threading model.
  2. You can't assign the owner for OpenMP threads
  3. No control over threads and internal threadpool